Android Intent.FLAG_NEW_TASK詳解,包括其餘的標記的一些解釋

1. Task是包含一系列Activity的堆棧, 遵循先進後出原則.

2. Task默認行爲:

(1)前提: Activity A和Activity B在同一個應用中.

  • 操做: Activity A啓動開僻Task堆棧(堆棧狀態: A), 在Activity A中啓動Activity B(堆棧狀態: AB), 按下BACK返回鍵(堆棧狀態: A).

(2)前提: Activity A和Activity B在同一個應用中, 應用名稱爲"TaskOne應用".

  • 操做: 在Launcher中單擊"TaskOne應用"圖標, Activity A啓動開僻Task堆棧, 命名爲TaskA(TaskA堆棧狀態: A), 在Activity A中啓動Activity B(TaskA堆棧狀態: AB), 長按Home鍵, 返回Launcher.啓動其它應用(如:電子書),開僻一個新Task堆棧, 命名: TaskB, 長按Home健, 返回Launcher, 單擊"TaskOne應用"圖標, 此時TaskA堆棧返回前臺,Activity B爲棧頂應用, 供用戶使用.

(3)前提: Activity A在名稱爲"TaskOne應用"的應用中, Activity C在名稱爲"TaskTwo應用"的應用中.

  • 操做: 在Launcher中單擊"TaskOne應用"圖標, Activity A啓動開僻Task堆棧, 命名爲TaskA(TaskA堆棧狀態: A),在Activity A中啓動Activity C(TaskA堆棧狀態: AC),長按Home鍵, 返回Launcher.啓動"TaskTwo應用"即Activity C, 開僻新的Task堆棧, 命名爲TaskB, 按BACK鍵返回Launcher, 單擊"TaskOne應用"圖標, 此時TaskA堆棧返回前臺, Activity C爲棧頂應用, 供用戶使用.

3. Intent FLAG介紹:

(1) FLAG_ACTIVITY_NEW_TASK:

設置此狀態,記住如下原則,首先會查找是否存在和被啓動的Activity具備相同的親和性的任務棧(即taskAffinity,注意同一個應用程序中的activity的親和性同樣,因此下面的a狀況會在同一個棧中,前面這句話有點拗口,請多讀幾遍),若是有,剛直接把這個棧總體移動到前臺,並保持棧中的狀態不變,即棧中的activity順序不變,若是沒有,則新建一個棧來存放被啓動的activity.net

  1. 前提: Activity A和Activity B在同一個應用中.對象

    • 操做: Activity A啓動開僻Task堆棧(堆棧狀態: A), 在Activity A中啓動Activity B, 啓動Activity B的Intent的Flag設爲FLAG_ACTIVITY_NEW_TASK, Activity B被壓入Activity A所在堆棧(堆棧狀態: AB).blog

    • 緣由: 默認狀況下同一個應用中的全部Activity擁有相同的關係(taskAffinity).圖片

  2. 前提: Activity A在名稱爲"TaskOne應用"的應用中, Activity C和Activity D在名稱爲"TaskTwo應用"的應用中.開發

    • 操做1: 在Launcher中單擊"TaskOne應用"圖標, Activity A啓動開僻Task堆棧, 命名爲TaskA(TaskA堆棧狀態: A),在Activity A中啓動Activity C, 啓動Activity C的Intent的Flag設爲FLAG_ACTIVITY_NEW_TASK,Android系統會爲Activity C開僻一個新的Task, 命名爲TaskB(TaskB堆棧狀態: C),長按Home鍵, 選擇TaskA, Activity A回到前臺, 再次啓動Activity C(兩種狀況1.從桌面啓動;2.從Activity A啓動,兩種狀況同樣), 這時TaskB回到前臺, Activity C顯示, 供用戶使用, 即: 包含FLAG_ACTIVITY_NEW_TASK的Intent啓動Activity的Task正在運行, 則不會爲該Activity建立新的Task,而是將原有的Task返回到前臺顯示.get

    • 操做2: 在Launcher中單擊"TaskOne應用"圖標, Activity A啓動開僻Task堆棧, 命名爲TaskA(TaskA堆棧狀態: A),在Activity A中啓動Activity C,啓動Activity C的Intent的Flag設爲FLAG_ACTIVITY_NEW_TASK,Android系統會爲Activity C開僻一個新的Task, 命名爲TaskB(TaskB堆棧狀態: C),在Activity C中啓動Activity D(TaskB的狀態: CD) 長按Home鍵, 選擇TaskA, Activity A回到前臺, 再次啓動Activity C(從桌面或者ActivityA啓動,也是同樣的), 這時TaskB回到前臺, Activity D顯示,供用戶使用.說明了在此種狀況下設置FLAG_ACTIVITY_NEW_TASK後,會先查找是否是有Activity C存在的棧,根據親和性(taskAffinity),若是有,剛直接把這個棧總體移動到前臺,並保持棧中的狀態不變,即棧中的順序不變it

(2) FLAG_ACTIVITY_CLEAR_TOP:

  • 前提: Activity A, Activity B, Activity C和Activity D在同一個應用中.email

  • 操做: Activity A啓動開僻Task堆棧(堆棧狀態: A), 在Activity A中啓動Activity B(堆棧狀態: AB), 在Activity B中啓動Activity C(堆棧狀態: ABC), 在Activity C中啓動Activity D(堆棧狀態: ABCD), 在Activity D中啓動Activity B,啓動Activity B的Intent的Flag設置爲FLAG_ACTIVITY_CLEAR_TOP, (堆棧狀態: AB).請求

(3) FLAG_ACTIVITY_BROUGHT_TO_FRONT:

  • 前提: Activity A在名稱爲"TaskOne應用"的應用中, Activity C和Activity D在名稱爲"TaskTwo應用"的應用中.程序

  • 操做: 在Launcher中單擊"TaskOne應用"圖標, Activity A啓動開僻Task堆棧, 命名爲TaskA(TaskA堆棧狀態: A), 在Activity A中啓動Activity C,啓動Activity C的Intent的Flag設爲FLAG_ACTIVITY_NEW_TASK,Android系統會爲Activity C開僻一個新的Task, 命名爲TaskB(TaskB堆棧狀態: C), 在Activity C中啓動Activity D(TaskB的堆棧狀態: CD), 長按Home鍵, 選擇TaskA, Activity A回到前臺, 在Activity A中再次啓動Activity C,在啓動Activity C的Intent中設置Flag爲FLAG_ACTIVITY_BROUGHT_TO_FRONT, TaskB回到前臺, Activity C顯示, (TaskB的堆棧狀態: C).

(4) FLAG_ACTIVITY_MULTIPLE_TASK:

(與FLAG_ACTIVITY_NEW_TASK結合使用)

  • 首先在Intent中設置FLAG_ACTIVITY_NEW_TASK, 打開Activity,則啓動一個新Task, 接着在Intent中設置FLAG_ACTIVITY_MULTIPLE_TASK, 再次打開同一個Activity,則還會新啓動一個Task.

(5) FLAG_ACTIVITY_SINGLE_TOP:

  • 當前Task堆棧中存在ABCD四個Activity, A是棧頂Activity, D爲棧底Activity, 存在打開A的Intent中設置了FLAG_ACTIVITY_SINGLE_TOP標誌, 則會使用棧頂A, 而不會重新New A.

(6) FLAG_ACTIVITY_RESET_TASK_IF_NEEDED:

  • 通常與FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET結合使用,若是設置該屬性,這個activity將在一個新的task中啓動或者被帶到一個已經存在的task的頂部,這時這個activity將會做爲這個task的首個頁面加載。將會致使與這個應用具備相同親和力的task處於一個合適的狀態(移動activity到這個task或者從中移出),或者簡單的重置這個task到它的初始狀態

(7)FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET:

在當前的Task堆棧中設置一個還原點,當帶有FLAG_ACTIVITY_RESET_TASK_IF_NEEDED的Intent請求啓動這個堆棧時(典型的例子是用戶從桌面再次啓動這個應用),還原點之上包括這個應用將會被清除。

  • 應用場景: 在email程序中預覽圖片時,會啓動圖片觀覽的actvity,當用戶離開email處理其餘事情,而後下次再次從home進入email時,咱們呈現給用戶的應該是上次email的會話,而不是圖片觀覽,這樣纔不會給用戶形成困惑。

  • 例: 存在Activity A, Activity B, Activity C, Activity A啓動開僻Task堆棧, 命名爲TaskA(TaskA堆棧狀態: A), 在Activity A中啓動Activity B(TaskA堆棧狀態: AB), 接着Activity B啓動Activity C(TaskA堆棧狀態: ABC), 啓動Activity C的Intent中設置FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET標題, 這樣TaskA中有一個還原點,當有包含FLAG_ACTIVITY_RESET_TASK_IF_NEEDED的Intent請求TaskA堆棧時(好比請求Activity A)系統就會將還原點以上的Activity清除, TaskA堆棧中只剩下了AB.

4. launchMode介紹:

(1) standard:

若是啓動此Activity的Intent中沒有設置FLAG_ACTIVITY_NEW_TASK標誌, 則這個Activity與啓動他的Activity在同一個Task中, 若是設置了Activity請參考上面FLAG_ACTIVITY_NEW_TASK的詳細說明。

"launchMode"設置爲"standard"的 Activity能夠被實例化屢次, 能夠在Task中的任何位置, 對於一個新的Intent請求就會實例化一次.

(2) singleTop:

若是啓動此Activity的Intent中沒有設置FLAG_ACTIVITY_NEW_TASK標誌, 則這個Activity與啓動他的Activity在同一個Task中, 若是設置了Activity請參考上面FLAG_ACTIVITY_NEW_TASK的詳細說明,

"launchMode"設置爲"singleTop"的Activity能夠被實例化屢次,  能夠在Task中的任何位置, 對於一個新的Intent請求若是在Task棧頂, 則會用棧頂的Activity響影Intent請求,而不會從新實例化對象接收請求, 若是沒有在棧頂, 則會實例化一個新的對象接收Intent請求.

(3) singleTask:

  • 設置了"singleTask"啓動模式的Activity,它在啓動的時候,會先在系統中查找屬性值affinity等於它的屬性值taskAffinity的任務存在;若是存在這樣的任務,它就會在這個任務中啓動,不然就會在新任務中啓動。所以,若是咱們想要設置了"singleTask"啓動模式的Activity在新的任務中啓動,就要爲它設置一個獨立的taskAffinity屬性值。

    • 知足條件:
      1. 立即將要啓動的Activity的launchMode爲"singleTask";
      2. 調用startActivity時不要求返回要啓動的Activity的執行結果;
      3. 當前系統不存在affinity屬性值等於即將要啓動的Activity的taskAffinity屬性值的任務
  • 若是設置了"singleTask"啓動模式的Activity不是在新的任務中啓動時,它會在已有的任務中查看是否已經存在相應的Activity實例,若是存在,就會把位於這個Activity實例上面的Activity所有結束掉,即最終這個Activity實例會位於任務的堆棧頂端中。

  • 參考: 解開Android應用程序組件Activity的"singleTask"之謎https://blog.csdn.net/luoshengyang/article/details/6714543

(4) singleInstance:

launchMode"設置爲"singleInstance"的Activity老是在棧底, 只能被實例化一次, 不容許其它的Activity壓入"singleInstance"的Activity所在Task棧,  即整個Task棧中只能有這麼一個Activity.

5. taskAffinity屬性:

taskAffinity屬性應和FLAG_ACTIVITY_NEW_TASK標誌及allowTaskReparenting屬性結合使用, 若是隻使用taskAffinity屬性,請參考上面Task默認的行爲.

與FLAG_ACTIVITY_NEW_TASK標誌結合:

  1. 前題: Activity A和Activity B在同一個應用中, Activity A與Activity B設置不一樣的taskAffinity屬性.

    • 操做: Activity A啓動開僻Task堆棧,命名爲TaskA(TaskA堆棧狀態: A), 在Activity A中啓動Activity B, 啓動Activity B的Intent中設置FLAG_ACTIVITY_NEW_TASK標誌,這時系統會新開僻一個Task堆棧,TaskB(TaskB堆棧狀態: B).
  2. 前題: Activity A在"TaskOne應用"中, Activity C在"TaskTwo應用"中, Activity A和ActivityC設置了相同的taskAffinity屬性.

    • 操做: Activity A啓動開僻Task堆棧,命名爲TaskA(TaskA堆棧狀態: A), 在Activity A中啓動Activity C, 啓動Activity C的 Intent中設置FLAG_ACTIVITY_NEW_TASK標誌,這時Activity C會壓入與Activity A堆棧相同的TaskA堆棧(TaskA堆棧狀態: AC).

與allowTaskReparenting屬性:

  • 例: 在"TaskOne應用"中有一個天氣預報Activity A, Activity A與"TaskOne應用"中的其它Activity有默認的關係(taskAffinity屬性都沒有設置), 而且allowTaskReparenting屬性設置爲true, 如今存在一個"TaskTwo應用"啓動了"TaskOne應用"中的天氣預報Activity A,  這時Activity A與"TaskTwo應用"中的Activity在同一個Task,  命名這個Task堆棧爲TaskA, 這時"TaskOne應用"啓動, 而且又打開發天氣預報Activity A, 這時Activity A會從TaskA堆棧中轉移到"TaskOne應用"所在的堆棧, 即Activity A能夠在多個堆棧中來回轉移.

6. alwaysRetainTaskState屬性:

若是Task堆棧中的Root Activity設置了此屬性值爲true, 無論出現任何狀況, 一直會保留Task棧中Activity的狀態.

7. clearTaskOnLaunch屬性:

若是Task堆棧中的Root Activity設置了此屬性值爲true, 只要你一離開這個Task棧, 則系統會立刻清理除了Root Activity的所有Activity.

8. finishOnTaskLaunch屬性:

若是某Activity設置了finishOnTaskLaunch屬性, 只要你一離開這個Task棧, 則系統會立刻清除這個Activity,無論這個Activity在堆棧的任何位置.

相關文章
相關標籤/搜索