眾所周知,在Manifest的activity標簽中有這么一個配置項android:launchMode霹崎,就是它決定著此activity的啟動模式将塑!
總共有四種模式褥赊,他們與Intent對象中的活動標志(FLAG_ACTIVITY_ *常量)結(jié)合使用,以確定Activity被喚起處理Intent時應該發(fā)生的情況熬的。 他們是:
standard: 默認痊硕。系統(tǒng)始終會在目標任務中創(chuàng)建新的 Activity 實例,并向其傳送 Intent押框。
singleTop:如果目標任務的頂部已存在 Activity 實例岔绸,則系統(tǒng)會通過調(diào)用該實例的 onNewIntent() 方法向其傳送 Intent,而非創(chuàng)建新的 Activity 實例橡伞。
singleTask:系統(tǒng)會在新任務的根位置創(chuàng)建 Activity 并向其傳送 Intent盒揉。不過,如果已存在 Activity 實例兑徘,則系統(tǒng)會調(diào)用該實例的 onNewIntent() 方法(而非創(chuàng)建新的 Activity 實例)刚盈,向其傳送 Intent。
singleInstance:與singleTask相同挂脑,只是系統(tǒng)不會將任何其他 Activity 啟動到包含實例的任務中藕漱。該 Activity 始終是其任務中的唯一 Activity欲侮。
小知識點梳理
以standard和singleTop模式啟動的Activity可以多次實例化,并且可以位于Activity棧中的任何位置肋联。
相比之下威蕉,以singleTask和singleInstance模式啟動的Activity 只能啟動任務。它們始終位于 Activity 棧的根位置橄仍。此外忘伞,設(shè)備一次只能保留一個 Activity 實例,即一次只允許一個此類任務沙兰。
singleTask和singleInstance模式同樣只有一處不同:singleTask模式的Activity 允許其他 Activity 成為其任務的一部分氓奈。該 Activity 始終位于其任務的根位置,但其他 Activity(必然是standard和singleTop模式的Activity)可以啟動到該任務中鼎天。另一方面舀奶,singleInstance模式的Activity 不允許其他 Activity 成為其任務的一部分。它是任務中唯一的 Activity斋射。如果它啟動另一個 Activity育勺,則系統(tǒng)會將該 Activity 分配給其他任務,就如同 Intent 中包含 FLAG_ACTIVITY_NEW_TASK 一樣罗岖。
實用命令:
可以查看棧信息
adb shell dumpsys activity activities
android:taskAffinity
taskAffinity這個配置項和啟動模式有著千絲萬縷的聯(lián)系涧至。可以翻譯成任務的相似性桑包。從概念上講南蓬,具有同一相似性的 Activity 歸屬同一任務(從用戶的角度來看递鹉,則是歸屬同一“應用”)盼忌。任務的相似性由其根 Activity 的相似性確定。
相似性確定兩點內(nèi)容 — Activity 更改父項后的任務(請參閱 allowTaskReparenting 屬性)刀荒,以及通過 FLAG_ACTIVITY_NEW_TASK 標記啟動 Activity 時弱左,用于容納該 Activity 的任務窄陡。
默認情況下,應用中的所有 Activity 都具有同一相似性拆火。您可以設(shè)置該屬性跳夭,以不同方式將其分組,甚至可以在同一任務內(nèi)放置不同應用中定義的 Activity们镜。如要指定 Activity 與任何任務均無相似性币叹,請將其設(shè)置為空字符串。
如果未設(shè)置該屬性憎账,則 Activity 會繼承為應用設(shè)置的相似性(請參閱 <application> 元素的 taskAffinity 屬性)套硼。應用默認相似性的名稱為 <manifest> 元素所設(shè)置的軟件包名稱卡辰。
android:allowTaskReparenting
當下一次將啟動 Activity 的任務轉(zhuǎn)至前臺時胞皱,Activity 是否能從該任務轉(zhuǎn)移至與其有相似性的任務 —“true”表示可以轉(zhuǎn)移邪意,“false”表示仍須留在啟動它的任務處。
如果未設(shè)置該屬性反砌,則對 Activity 應用由 <application> 元素的相應 allowTaskReparenting 屬性所設(shè)置的值雾鬼。默認值為“false”。
正常情況下宴树,Activity 啟動時會與啟動它的任務關(guān)聯(lián)策菜,并在其整個生命周期中一直留在該任務處。當不再顯示現(xiàn)有任務時酒贬,您可以使用該屬性強制 Activity 將其父項更改為與其有相似性的任務又憨。該屬性通常用于將應用的 Activity 轉(zhuǎn)移至與該應用關(guān)聯(lián)的主任務。
例如锭吨,如果電子郵件消息包含網(wǎng)頁鏈接蠢莺,則點擊該鏈接會調(diào)出可顯示該網(wǎng)頁的 Activity。該 Activity 由瀏覽器應用定義零如,但作為電子郵件任務的一部分啟動躏将。如果將該 Activity 的父項更改為瀏覽器任務,則它會在瀏覽器下一次轉(zhuǎn)至前臺時顯示考蕾,在電子郵件任務再次轉(zhuǎn)至前臺時消失祸憋。
Activity 的相似性由 taskAffinity 屬性定義。通過讀取任務根 Activity 的相似性即可確定任務的相似性肖卧。因此蚯窥,按照定義,根 Activity 始終位于具有同一相似性的任務中塞帐。由于具有“singleTask”或“singleInstance”啟動模式的 Activity 只能位于任務的根沟沙,因此更改父項僅限于“standard”和“singleTop”模式。(另請參閱 launchMode 屬性壁榕。)
啟動標志位
提到啟動模式矛紫,Intent中的啟動標志位就是不得不看的一個內(nèi)容了。
- FLAG_ACTIVITY_NEW_TASK
這個標志位可以算是大名鼎鼎了牌里。相對也比較熟悉颊咬。當需要在一個新的任務中啟動Activity時,加上次標志位牡辽。
Launcher在啟動應用的時候就會統(tǒng)一加上這個標志位喳篇。
如果使用Service啟動Activity的話,也需要加上這個态辛。
當使用此標志位時麸澜,如果有一個任務已經(jīng)在運行你想要啟動的Activity,此時奏黑,不會有一個新的Activity被啟動炊邦,取而代之的是编矾,當前這個任務將簡單地以其上次進入的狀態(tài)顯示在屏幕的前面。有關(guān)禁用此行為的標志馁害,請參見FLAG_ACTIVITY_MULTIPLE_TASK窄俏。
當調(diào)用者從正在啟動的Activity中請求結(jié)果時,不能使用此標志碘菜。 - FLAG_ACTIVITY_CLEAR_TOP
如果設(shè)置了這個標志位凹蜈,那么在啟動一個Activity時,如果這個Activity已經(jīng)在當前任務中了忍啸,那么所有在這個Activity以上的Activity都會被關(guān)閉仰坦,這個Intent會以new Intent的形式被分發(fā)給舊的那個Activity,當然计雌,在這個舊Activity頭上的兄弟被關(guān)閉之后缎岗,他現(xiàn)在已經(jīng)在棧頂了。
舉個例子:
有任務棧中已經(jīng)存在4個Activity A白粉、B传泊、C、D鸭巴,其中A在棧底眷细,D在棧頂,也就是說顯示的是Activity D鹃祖。此時Activity D用FLAG_ACTIVITY_CLEAR_TOP的標志位啟動Activity B溪椎,那么C和D會被finish掉,B會收到新的Intent恬口,最后棧里之身下A校读、B。
對于上面例子中的Activity B祖能,在他被啟動時歉秫,要么通過onNewIntent方法,要么通過finish之后重啟养铸。如果他的啟動模式被聲明為"multiple" (the default)雁芙,同時Intent中沒有設(shè)置FLAG_ACTIVITY_SINGLE_TOP,那么他將被重啟钞螟。對于其他的啟動模式兔甘,或者設(shè)置了FLAG_ACTIVITY_SINGLE_TOP的情況,他的onNewIntent方法會被調(diào)用鳞滨。
此啟動模式也可以與FLAG_ACTIVITY_NEW_TASK結(jié)合使用洞焙,以達到良好效果:如果用來啟動任務中的根Activity,它將把該任務的任何當前正在運行的實例置于前臺,然后將其清除為根狀態(tài)澡匪。例如熔任,當從通知欄啟動Activity時,此功能特別有用仙蛉。 - FLAG_ACTIVITY_SINGLE_TOP
和singleTop啟動模式一致