AndroidManifest.xml
中指定launchMode
standard
標準模式,每次啓動Activity
都會建立一個新的Activity
實例,而且將其壓入任務棧棧頂,而無論這個 Activity 是否已經存在,都會執行onCreate() ->onStart() -> onResume
。android
singleTop
棧頂複用模式,若是新Activity
已經位於棧頂,那麼此Activity
不會被從新建立,同時Activity
的 onNewIntent
方法會被回調,若是Activity
已經存在可是再也不棧頂,那麼和standard
模式同樣。 若是Activity
當前是onResume
狀態,那麼調用後會執行onPause() -> onNewIntent() -> onResume()
。bash
singleTask
棧內複用模式,建立這樣的Activity
,系統會確認它所需任務棧是否已經建立,不然先建立任務棧,而後放入Activity
,若是棧中已經有一個Activity
實例,那麼會作兩件事:this
Activity
會回到棧頂執行onNewIntent
Activity
上面的全部Activity
上面的若是棧中已經有一個Activity
實例,這個判斷條件的**標準是由android:taskAffinity
**決定的,下面咱們作一個簡單的對比:spa
singleTask
的Activity
設置taskAffinity
,這時默認狀況下屬於同一個Application
的全部Activity
具備的taskAffinity
是相同的,就是咱們在AndroidManifest
中指定的packageName
:<activity android:name=".SingleTaskActivity" android:launchMode="singleTask"/>
複製代碼
這時候咱們從MainActivity
啓動SingleTaskActivity
後,任務棧的狀況是,MainActivity
和 SingleTaskActivity
處於同一個Task
當中: code
SingleTaskActivity
和
MainActivity
位於同一個棧中,所以
singleTask
並非讓這個
Activity
獨佔一個
Task
。
singleTask
的Activity
設置affinity
:<activity android:name=".SingleTaskActivity" android:launchMode="singleTask" android:taskAffinity="com.android.singleTask"/>
複製代碼
此時進行一樣的操做,任務棧的狀況變爲: xml
SingleTaskActivity
的界面按下
Home
鍵,再點擊圖標進入
MainActivity
,能夠看到當前應用有兩個棧:
SingleTaskActivity
,那麼會執行
MainActivity#onPause
SingleTaskActivity#onNewIntent
SingleTaskActivity#onRestart
SingleTaskActivity#onStart
SingleTaskActivity#onResume
MainActivity#onStop
複製代碼
這是因爲當啓動SingleTaskActivity
,系統去尋找該SingleTaskActivity
所對應的棧是否存在,而這時候是存在的,也就上面看到TaskRecord[cd9ca5d]
,因此它不會建立新的SingleTaskActivity
,而是複用這個棧中的Activity
,而因爲這個Activity
又位於棧頂,所以它的表現和SingleTop
相同。排序
SingleTaskActivity
所在的Task
上再加一個 SingleTaskAboveActivity
,首先咱們從MainAcitivity -> SingleTaskActivity -> SingleTaskAboveActvity
<activity android:name=".SingleTaskAboveActivity"/>
複製代碼
這一流程事後,棧的結構爲,能夠看到SingleTaskActivity
和SingleTaskAboveActvity
位於同一棧中:生命週期
SingleTaskAboveActvity
界面,按
Home
退到後臺以後從新進入,棧的結構不變,只不過當前可見的是
MainActivity
,這時咱們再次嘗試啓動
SingleTaskActivity
,那麼會依次調用:
MainActivity#onPause
SingleTaskAboveActivity#onDestroy
SingleTaskActivity#onNewIntent
SingleTaskActivity#onRestart
SingleTaskActivity#onStart
SingleTaskActivity#onResume
MainActivity#onStop
複製代碼
而棧的結構變爲以下: ip
SingleTaskActivity
時,系統去尋找該
SingleTaskActivity
所對應的棧是否存在,而這時候是存在的,也就上面看到
TaskRecord[a3771ca]
,因此它不會建立新的
SingleTaskActivity
,而是複用這個棧中的
SingleTaskActivity
,但此時
SingleTaskActivity
並不位於棧頂,在它上面還有一個
SingleTaskAboveActivity
,所以會把
SingleTaskAboveActivity
先出棧,再複用原先位於這個棧中的
SingleTaskActivity
實例。
singleInstance
這種模式的Activity
只能單獨位於一個任務棧內,因爲棧內的複用特性,後續請求均不會建立新的Activity
,除非這個獨特的任務棧被系統銷燬了。ci
SingleInstanceActivity
<activity android:name=".SingleInstanceActivity" android:launchMode="singleInstance"/>
複製代碼
咱們從MainAcitivity
啓動它,此時任務棧的狀況是,他們位於不一樣的Task
中,符合咱們的預期:
Home
回到桌面,再從新點圖標進入MainActivity
,任務棧依然是兩個,咱們此時再啓動SingleInstanceActivity
:MainActivity#onPause
SingleInstanceActivity#onNewIntent
SingleInstanceActivity#onRestart
SingleInstanceActivity#onStart
SingleInstanceActivity#onResume
MainActivity#onStop
複製代碼
和啓動在另外一個棧中已存在的singleTaskAcitivity
的狀況是相似的。
affinity
對於singleInstance
會不會有影響呢,咱們定義兩個affinity
相同的 singleInstance
:<activity android:name=".SingleInstanceActivity" android:launchMode="singleInstance" android:taskAffinity="com.android.singleInstance"/>
<activity android:name=".SingleInstanceActivityAnother" android:launchMode="singleInstance" android:taskAffinity="com.android.singleInstance"/>
複製代碼
咱們先從MainActivity
啓動SingleInstanceActivity
,按Home
回到桌面再進入,此時Task
的狀況和上面相同的,那麼這時候咱們啓動SingleInstanceActivityAnother
:
affinity
的影響,而是從新起了一個新的棧。
Intent
當中指定啓動模式FLAG_ACTIVITY_NEW_TASK
和singleTask
行爲相同,前面已經詳細分析過了,這裏須要注意 affinity 的聲明。
FLAG_ACTIVITY_SINGLE_TOP
和singleTop
行爲相同,比較簡單,就不舉例子了。
FLAG_ACTIVITY_CLEAR_TASK
和 FLAG_ACTIVITY_NEW_TASK
何用,這個Activity
會新起一個棧,原來棧被清空,棧中的Activity
也被銷燬。
FLAG_ACTIVITY_CLEAR_TOP
會清除這個Activity
之上全部的Activity
,咱們來試一下,新建兩個新的SecondActivity
和ThirdActivity
,從Main -> Second -> Third
,此時棧的結構是:
SecondActivity
:
public void third(View view) {
Intent intent = new Intent(this, SecondActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
複製代碼
這以後,棧的結構變爲,ThirdAcitivity
被出棧了:
FLAG_ACTIVITY_REORDER_TO_FRONT
上面的FLAG_ACTIVITY_CLEAR_TOP
是把位於目標Activity
之上的Activity
都銷燬,而則個FLAG
則是對棧從新排序,把目標Activity
移到最前臺,其它的位置不變,咱們在前一種的基礎上,在ThirdActivity
中換一種方式來啓動SecondActivity
:
public void third(View view) {
Intent intent = new Intent(this, SecondActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
}
複製代碼
這回,最終棧的結構變爲了,能夠看到ThirdActivity
並無被出棧:
AndroidManifest
中的屬性alwaysRetainTaskState
這個標誌只對根Activity
有用,默認狀況下,當咱們的應用在後臺一段時間,它會銷燬該Task
除了根之外的全部Activity
,若是咱們但願保持這個Task
的原有狀態,那麼給這個Task
的根Activity
設置這個屬性,默認值是false
。
clearTaskOnLaunch
從桌面啓動該Activity
的時候會清空該Task
除了根Activity
外的全部Activity
,咱們從Main -> Second -> Third
,此時棧內有3個Activity
,按Home
回到桌面後,點圖標從新進入,此時Task
只剩下根Activity
了:
finishOnTaskLaunch
這個和上面相似,可是它對根Activity
無效,咱們給SecondActivity
設置這個屬性,先啓動到ThirdActivity
,這時候棧的結構爲:
接着,咱們按Home
回到桌面,點圖標從新進入,棧的結構變爲下面這樣,能夠看到SecondActivity
沒有了:
noHistory
Activity
在不可見以後,不保存記錄
SecondActivity
設置這個屬性,接着從Main -> Second -> Third
,而後按Back
返回,此時的生命週期爲:ThirdActivity#onPause
MainActivity#onRestart
MainActivity#onStart
MainActivity#onResume
SecondActivity#onDestroy
ThirdActivity#onStop
ThirdActivity#onDestroy
複製代碼
ThirdActivity
時,不是按Back
,而是按Home
到桌面,會調用:ThirdActivity#onPause
SecondActivity#onDestroy
ThirdActivity#onStop
複製代碼
MainAcitivity
設置這個屬性,啓動它後退出:MainActivity#onCreate
MainActivity#onStart
MainActivity#onResume
MainActivity#onDestory
複製代碼