Activity 啓動模式,熟知的就是 standard、singleTop、singleTask、singleInstance
注意點:
任務棧 -- 所有Activity繼承Application 的任務棧名稱,即包名。
只有 singleTask 啓動模式的Activity 單獨設置任務棧名稱有意義。
任務棧名稱不可與包名一致,設置方式爲在清單文件。
android:taskAffinity="com.yanlong.task1"
1、standard 啓動模式,誰加載我,我進入誰的任務棧;
2、ApplicationContext 啓動 standard 模式的Activity 報錯,因爲 非Activity類型的Context 無所謂 任務棧。解決方法,給待啓動Activity指定 FLAG_ACTIVITY_NEW_TASK
Intent intent = new Intent(); intent.setClass(MainActivity.this,SecondActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent);3、singleTop:如果啓動的新AC已經屬於棧頂,那麼會調用 onNewIntent。
4、singleTask:如果存在,多次啓動,調用onNewIntent。
重要:singleTask 啓動方式 --- 先檢查是否有所需 任務棧,再檢查是否有所需實例。
舉例:
任務棧名稱 默認包名 如 com.yanlong.myapplication
任務棧名稱 自定義棧名 如 com.yanlong.task
A:MainActivity 任務棧名稱 默認包名,默認打開 standard
B:SecondActivity 任務棧名稱 默認包名,打開方式 standard
C:ThreadActivity 任務棧名稱 自定義棧名,打開方式 singleTask
D:FourActivity 任務棧名稱 自定義棧名,打開方式 singleTask
啓動流程 A->B->C->D->B
A啓動B,由於B是 standard,那麼B直接進入 默認包名棧
B啓動C,由於C是 singleTask,那麼C先查找 自定義棧名,沒有找到,那麼先創建 自定義棧名,然後創建C實例,壓入自定義棧名任務棧
C啓動D,由於自定義棧名已經存在,然後查找該棧名內是否有 D實例,沒有找到,那麼創建D實例,壓入自定義棧名任務棧
D啓動B,由於B是 standard,那麼B直接進入 自定義棧名任務棧
所以最後結果
默認棧內:A B
自定義棧內:C D B
TaskAffinity屬性主要和singleTask啓動模式或者 allowTaskReparenting屬性配對使用,在其他情況下沒有意義。另外,任務棧分爲前臺任務棧和後臺任務棧,後臺任務棧中的Activity位於暫停狀態,用戶可以通過 切換將後臺任務棧再次調到前臺。
這裏前臺任務棧 後臺任務棧不是很明朗,根據書中所寫,我個人見解是,當前顯示的 Activity所在的棧區是前臺任務棧,其他的任務棧都是後臺任務棧。希望有了解的留言糾正。
重點:
當TaskAffinity和allowTaskReparenting結合的時候,會產生特殊效果
應用 M,應用 N
N中 Activity N-A,屬性 allowTaskReparenting 爲 true
M 啓動了 N-A。然後按Home回到桌面,單擊N的桌面圖標,顯示界面不是 N的MainActivity 而是 N-A
解釋:
M 啓動了 N-A,這時候 N-A 只能運行在 M的任務棧中,但是N-A屬於N應用,正常情況下,他的TaskAffinity值肯定和M不同,因爲包名不同。所以當N啓動時,N會創建自己的任務棧,這時候系統發現 N-A原本想要的任務棧被創建了,所以就把N-A從M的任務棧 轉移了過來。