天天看點

Android Intent.FLAG_NEW_TASK詳解,包括其他的标記的一些解釋

對原文中的講解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介紹:

設定此狀态,記住以下原則,首先會查找是否存在和被啟動的Activity具有相同的親和性的任務棧(即taskAffinity,注意同一個應用程式中的activity的親和性一樣,是以下面的a情況會在同一個棧中,前面這句話有點拗口,請多讀幾遍),如果有,剛直接把這個棧整體移動到前台,并保持棧中的狀态不變,即棧中的activity順序不變,如果沒有,則建立一個棧來存放被啟動的activity

         a. 前提: 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).

預設情況下同一個應用中的所有Activity擁有相同的關系(taskAffinity).

         b. 前提: 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,

兩種情況1.從桌面啟動;2.從Activity A啟動,兩種情況一樣), 這時TaskB回到前台, Activity C顯示, 供使用者使用, 即:

包含FLAG_ACTIVITY_NEW_TASK的Intent啟動Activity的Task正在運作, 則不會為該Activity建立新的Task,

                       而是将原有的Task傳回到前台顯示.

             操作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中啟動

從桌面或者ActivityA啟動,也是一樣的),

FLAG_ACTIVITY_NEW_TASK後,會先查找是不是有Activity C存在的棧,根據親和             性(taskAffinity),如果有,剛直接把這個棧整體移動到前台,并保持棧中的狀态不變,即棧中的順序不變

    (2) FLAG_ACTIVITY_CLEAR_TOP:

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

         操作: 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到它的初始狀态

   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: 

        "launchMode"設定為"singleTask"的Activity總是在棧底, 隻能被執行個體化一次, 它允許其它Activity壓入"singleTask"的Activity

         所在的Task棧,如果有新的Intent請求有此标志的Activity, 則系統會清除有此标志的Task棧中的全部Activity,并把此Activity顯示出來.

   (4) singleInstance: 

         launchMode"設定為"singleInstance"的Activity總是在棧底, 隻能被執行個體化一次, 不允許其它的Activity壓入"singleInstance"

         的Activity所在Task棧,  即整個Task棧中隻能有這麼一個Activity.

5. taskAffinity屬性: 

   (1) taskAffinity屬性應和FLAG_ACTIVITY_NEW_TASK标志及allowTaskReparenting屬性結合使用, 如果隻使用taskAffinity屬性,

        請參考上面Task預設的行為.

   (2) 與FLAG_ACTIVITY_NEW_TASK标志結合:

       a. 前題: 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).

       b. 前題: 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).

   (3) 與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.

繼續閱讀