一漠趁、AndroidManifest.xml
中指定launchMode
1.1standard
標(biāo)準(zhǔn)模式,每次啟動(dòng)Activity
都會(huì)創(chuàng)建一個(gè)新的Activity
實(shí)例酥艳,并且將其壓入任務(wù)棧棧頂,而不管這個(gè) Activity 是否已經(jīng)存在,都會(huì)執(zhí)行onCreate() ->onStart() -> onResume
澡屡。
1.2 singleTop
棧頂復(fù)用模式,如果新Activity
已經(jīng)位于棧頂咐旧,那么此Activity
不會(huì)被重新創(chuàng)建驶鹉,同時(shí)Activity
的 onNewIntent
方法會(huì)被回調(diào),如果Activity
已經(jīng)存在但是不再棧頂铣墨,那么和standard
模式一樣室埋。
如果Activity
當(dāng)前是onResume
狀態(tài),那么調(diào)用后會(huì)執(zhí)行onPause() -> onNewIntent() -> onResume()
伊约。
1.3 singleTask
棧內(nèi)復(fù)用模式姚淆,創(chuàng)建這樣的Activity
,系統(tǒng)會(huì)確認(rèn)它所需任務(wù)棧是否已經(jīng)創(chuàng)建屡律,否則先創(chuàng)建任務(wù)棧腌逢,然后放入Activity
,如果棧中已經(jīng)有一個(gè)Activity
實(shí)例疹尾,那么會(huì)做兩件事:
- 這個(gè)
Activity
會(huì)回到棧頂執(zhí)行onNewIntent
- 清理在當(dāng)前
Activity
上面的所有Activity
上面的如果棧中已經(jīng)有一個(gè)Activity
實(shí)例上忍,這個(gè)判斷條件的標(biāo)準(zhǔn)是由android:taskAffinity
決定的骤肛,下面我們做一個(gè)簡(jiǎn)單的對(duì)比:
- 第一種情況纳本,不給
singleTask
的Activity
設(shè)置taskAffinity
窍蓝,這時(shí)默認(rèn)情況下屬于同一個(gè)Application
的所有Activity
具有的taskAffinity
是相同的,就是我們?cè)?code>AndroidManifest中指定的packageName
:
<activity android:name=".SingleTaskActivity" android:launchMode="singleTask"/>
這時(shí)候我們從MainActivity
啟動(dòng)SingleTaskActivity
后繁成,任務(wù)棧的情況是吓笙,MainActivity
和 SingleTaskActivity
處于同一個(gè)Task
當(dāng)中:
我們看到
SingleTaskActivity
和MainActivity
位于同一個(gè)棧中,因此singleTask
并不是讓這個(gè)Activity
獨(dú)占一個(gè)Task
巾腕。
- 第二種情況面睛,給
singleTask
的Activity
設(shè)置affinity
:
<activity android:name=".SingleTaskActivity" android:launchMode="singleTask" android:taskAffinity="com.android.singleTask"/>
此時(shí)進(jìn)行同樣的操作,任務(wù)棧的情況變?yōu)椋?br>
我們?cè)?code>SingleTaskActivity的界面按下
Home
鍵尊搬,再點(diǎn)擊圖標(biāo)進(jìn)入MainActivity
叁鉴,可以看到當(dāng)前應(yīng)用有兩個(gè)棧:
此時(shí),我們?cè)冱c(diǎn)擊按鈕啟動(dòng)
SingleTaskActivity
佛寿,那么會(huì)執(zhí)行
MainActivity#onPause
SingleTaskActivity#onNewIntent
SingleTaskActivity#onRestart
SingleTaskActivity#onStart
SingleTaskActivity#onResume
MainActivity#onStop
這是由于當(dāng)啟動(dòng)SingleTaskActivity
幌墓,系統(tǒng)去尋找該SingleTaskActivity
所對(duì)應(yīng)的棧是否存在,而這時(shí)候是存在的冀泻,也就上面看到TaskRecord[cd9ca5d]
常侣,所以它不會(huì)創(chuàng)建新的SingleTaskActivity
,而是復(fù)用這個(gè)棧中的Activity
弹渔,而由于這個(gè)Activity
又位于棧頂胳施,因此它的表現(xiàn)和SingleTop
相同。
- 第三種情況肢专,我們?cè)囍诘诙N的基礎(chǔ)上再加大一些難度舞肆, 在
SingleTaskActivity
所在的Task
上再加一個(gè)SingleTaskAboveActivity
,首先我們從MainAcitivity -> SingleTaskActivity -> SingleTaskAboveActvity
<activity android:name=".SingleTaskAboveActivity"/>
這一流程過后博杖,棧的結(jié)構(gòu)為椿胯,可以看到SingleTaskActivity
和SingleTaskAboveActvity
位于同一棧中(雖然我們并沒有聲明SingleTaskAboveActivity
的taskAffinity
為com.android.singleTask
):
在
SingleTaskAboveActvity
界面,按Home
退到后臺(tái)之后重新進(jìn)入欧募,棧的結(jié)構(gòu)不變压状,只不過當(dāng)前可見的是 MainActivity
,這時(shí)我們?cè)俅螄L試啟動(dòng)SingleTaskActivity
跟继,那么會(huì)依次調(diào)用:
MainActivity#onPause
SingleTaskAboveActivity#onDestroy
SingleTaskActivity#onNewIntent
SingleTaskActivity#onRestart
SingleTaskActivity#onStart
SingleTaskActivity#onResume
MainActivity#onStop
而棧的結(jié)構(gòu)變?yōu)槿缦拢?br>
和第二種情況類似种冬,當(dāng)啟動(dòng)
SingleTaskActivity
時(shí),系統(tǒng)去尋找該SingleTaskActivity
所對(duì)應(yīng)的棧是否存在舔糖,而這時(shí)候是存在的娱两,也就上面看到TaskRecord[a3771ca]
,所以它不會(huì)創(chuàng)建新的SingleTaskActivity
金吗,而是復(fù)用這個(gè)棧中的SingleTaskActivity
十兢,但此時(shí)SingleTaskActivity
并不位于棧頂趣竣,在它上面還有一個(gè)SingleTaskAboveActivity
,因此會(huì)把SingleTaskAboveActivity
先出棧旱物,再復(fù)用原先位于這個(gè)棧中的SingleTaskActivity
實(shí)例遥缕。
1.4 singleInstance
這種模式的Activity
只能單獨(dú)位于一個(gè)任務(wù)棧內(nèi),由于棧內(nèi)的復(fù)用特性宵呛,后續(xù)請(qǐng)求均不會(huì)創(chuàng)建新的Activity
单匣,除非這個(gè)獨(dú)特的任務(wù)棧被系統(tǒng)銷毀了。
- 第一種情況宝穗,先看最簡(jiǎn)單的户秤,我們新建一個(gè)
SingleInstanceActivity
<activity android:name=".SingleInstanceActivity" android:launchMode="singleInstance"/>
我們從MainAcitivity
啟動(dòng)它,此時(shí)任務(wù)棧的情況是逮矛,他們位于不同的Task
中鸡号,符合我們的預(yù)期:
- 第二種情況,此時(shí)按
Home
回到桌面须鼎,再重新點(diǎn)圖標(biāo)進(jìn)入MainActivity
鲸伴,任務(wù)棧依然是兩個(gè),我們此時(shí)再啟動(dòng)SingleInstanceActivity
:
MainActivity#onPause
SingleInstanceActivity#onNewIntent
SingleInstanceActivity#onRestart
SingleInstanceActivity#onStart
SingleInstanceActivity#onResume
MainActivity#onStop
和啟動(dòng)在另一個(gè)棧中已存在的singleTaskAcitivity
的情況是類似的莉兰。
- 第三種情況挑围,我們?cè)倏匆幌拢?code>affinity對(duì)于
singleInstance
會(huì)不會(huì)有影響呢,我們定義兩個(gè)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
啟動(dòng)SingleInstanceActivity
糖荒,按Home
回到桌面再進(jìn)入杉辙,此時(shí)Task
的情況和上面相同的,那么這時(shí)候我們啟動(dòng)SingleInstanceActivityAnother
:
可以看到捶朵,它并沒有受到
affinity
的影響蜘矢,而是重新起了一個(gè)新的棧。
二综看、在Intent
當(dāng)中指定啟動(dòng)模式
2.1 FLAG_ACTIVITY_NEW_TASK
和singleTask
行為相同品腹,前面已經(jīng)詳細(xì)分析過了,這里需要注意 affinity 的聲明红碑。
2.2 FLAG_ACTIVITY_SINGLE_TOP
和singleTop
行為相同舞吭,比較簡(jiǎn)單,就不舉例子了析珊。
2.3 FLAG_ACTIVITY_CLEAR_TASK
和 FLAG_ACTIVITY_NEW_TASK
何用羡鸥,這個(gè)Activity
會(huì)新起一個(gè)棧,原來?xiàng)1磺蹇罩已埃瑮V械?code>Activity也被銷毀惧浴。
2.5 FLAG_ACTIVITY_CLEAR_TOP
會(huì)清除這個(gè)Activity
之上所有的Activity
,我們來試一下奕剃,新建兩個(gè)新的SecondActivity
和ThirdActivity
衷旅,從Main -> Second -> Third
捐腿,此時(shí)棧的結(jié)構(gòu)是:
此時(shí),我們按如下方式啟動(dòng)
SecondActivity
:
public void third(View view) {
Intent intent = new Intent(this, SecondActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
這之后柿顶,棧的結(jié)構(gòu)變?yōu)椋?code>ThirdAcitivity被出棧了:
2.6 FLAG_ACTIVITY_REORDER_TO_FRONT
上面的FLAG_ACTIVITY_CLEAR_TOP
是把位于目標(biāo)Activity
之上的Activity
都銷毀茄袖,而則個(gè)FLAG
則是對(duì)棧重新排序,把目標(biāo)Activity
移到最前臺(tái)九串,其它的位置不變绞佩,我們?cè)谇耙环N的基礎(chǔ)上寺鸥,在ThirdActivity
中換一種方式來啟動(dòng)SecondActivity
:
public void third(View view) {
Intent intent = new Intent(this, SecondActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
}
這回猪钮,最終棧的結(jié)構(gòu)變?yōu)榱耍梢钥吹?code>ThirdActivity并沒有被出棧:
三胆建、AndroidManifest
中的屬性
3.1 alwaysRetainTaskState
這個(gè)標(biāo)志只對(duì)根Activity
有用烤低,默認(rèn)情況下,當(dāng)我們的應(yīng)用在后臺(tái)一段時(shí)間笆载,它會(huì)銷毀該Task
除了根以外的所有Activity
扑馁,如果我們希望保持這個(gè)Task
的原有狀態(tài),那么給這個(gè)Task
的根Activity
設(shè)置這個(gè)屬性凉驻,默認(rèn)值是false
腻要。
3.2 clearTaskOnLaunch
從桌面啟動(dòng)該Activity
的時(shí)候會(huì)清空該Task
除了根Activity
外的所有Activity
,我們從Main -> Second -> Third
涝登,此時(shí)棧內(nèi)有3個(gè)Activity
雄家,按Home
回到桌面后,點(diǎn)圖標(biāo)重新進(jìn)入胀滚,此時(shí)Task
只剩下根Activity
了:
3.3 finishOnTaskLaunch
這個(gè)和上面類似趟济,但是它對(duì)根Activity
無效,我們給SecondActivity
設(shè)置這個(gè)屬性咽笼,先啟動(dòng)到ThirdActivity
顷编,這時(shí)候棧的結(jié)構(gòu)為:
接著,我們按Home
回到桌面剑刑,點(diǎn)圖標(biāo)重新進(jìn)入媳纬,棧的結(jié)構(gòu)變?yōu)橄旅孢@樣,可以看到SecondActivity
沒有了:
3.4 noHistory
Activity
在不可見之后施掏,不保存記錄
- 第一種情況钮惠,我們給
SecondActivity
設(shè)置這個(gè)屬性,接著從Main -> Second -> Third
其监,然后按Back
返回萌腿,此時(shí)的生命周期為:
ThirdActivity#onPause
MainActivity#onRestart
MainActivity#onStart
MainActivity#onResume
SecondActivity#onDestroy
ThirdActivity#onStop
ThirdActivity#onDestroy
- 第二種情況,如果我們?cè)?code>ThirdActivity時(shí)抖苦,不是按
Back
毁菱,而是按Home
到桌面米死,會(huì)調(diào)用:
ThirdActivity#onPause
SecondActivity#onDestroy
ThirdActivity#onStop
- 第三種情況,我們給根
MainAcitivity
設(shè)置這個(gè)屬性贮庞,啟動(dòng)它后退出:
MainActivity#onCreate
MainActivity#onStart
MainActivity#onResume
MainActivity#onDestory