為什么需要啟動(dòng)模式
Android系統(tǒng)使用任務(wù)棧的結(jié)構(gòu)存放Activity的實(shí)例槽奕,眾所周知几睛,棧結(jié)構(gòu)遵循先進(jìn)后出的執(zhí)行原則。所以這就是為什么當(dāng)你按回退鍵的時(shí)候之前的頁(yè)面會(huì)一個(gè)個(gè)彈出來(lái)史翘,當(dāng)這個(gè)任務(wù)棧存放的Activity實(shí)例都被彈出棧的時(shí)候枉长,你就回到了手機(jī)桌面冀续。相信很多QA們?cè)跍y(cè)試的時(shí)候都會(huì)發(fā)現(xiàn)一個(gè)問(wèn)題,頁(yè)面中的一個(gè)按鈕快速點(diǎn)擊多下必峰,會(huì)打開(kāi)好幾個(gè)二級(jí)頁(yè)面洪唐,這就是Activtiy默認(rèn)啟動(dòng)模式在起作用。
啟動(dòng)模式
- standard(標(biāo)準(zhǔn)模式吼蚁,也是默認(rèn)模式)
- singleTop(棧頂復(fù)用)
- singleTask(棧內(nèi)復(fù)用)
- singleInstance(單實(shí)例模式)
特點(diǎn)
1.standard
每次啟動(dòng)一個(gè)Activity都會(huì)創(chuàng)建一個(gè)新的實(shí)例凭需。這種模式下,遵循的一個(gè)原則是誰(shuí)啟動(dòng)的肝匆,這個(gè)實(shí)例就會(huì)添加到啟動(dòng)他的那個(gè)Activity所在的棧中粒蜈。可以這樣理解旗国,你在應(yīng)用1的Activity_A中啟動(dòng)了應(yīng)用2的Activity_C枯怖,當(dāng)你再打開(kāi)應(yīng)用2的時(shí)候會(huì)進(jìn)入應(yīng)用2的啟動(dòng)頁(yè)Activity_B,而不是應(yīng)用2的Activity_C;
2.singleTask
每次啟動(dòng)一個(gè)Activity能曾,比如Activity_A度硝,會(huì)先去尋找這個(gè)Activity_A想要的任務(wù)棧(應(yīng)用中的Activity默認(rèn)運(yùn)行在自己應(yīng)用的任務(wù)棧中,后續(xù)深入講解)寿冕,不存在就創(chuàng)建任務(wù)棧然后創(chuàng)建Activity_A實(shí)例并入棧蕊程。如果想要的任務(wù)棧存在,并且棧內(nèi)有這個(gè)Activity_A的實(shí)例則復(fù)用驼唱,將棧內(nèi)該實(shí)例以上的其他Activity實(shí)例順次彈出棧藻茂,則我們需要啟動(dòng)的Activity_A就回到棧頂并調(diào)用它的onNewIntent(之后onResume);如果棧內(nèi)實(shí)例不存在玫恳,就創(chuàng)建實(shí)例并壓入棧辨赐。
3.singleTop
此模式和singleTask類(lèi)似,例如纽窟,如果當(dāng)前需要啟動(dòng)的Activity_A位于任務(wù)棧的棧頂肖油,則復(fù)用這個(gè)Activity_A的實(shí)例并調(diào)用它的onNewIntent(之后onResume)。如果需要啟動(dòng)的Activity_A的實(shí)例不處于棧頂臂港,而在棧中,則需要重新創(chuàng)建實(shí)例并壓入棧视搏。
4.singleInstance
這個(gè)啟動(dòng)模式相對(duì)比較特殊审孽。它除了具有singleTask的一切特性外,顯著的一個(gè)特點(diǎn)是這種啟動(dòng)模式的Activity只能單獨(dú)位于一個(gè)任務(wù)棧內(nèi)浑娜;系統(tǒng)為其分配一個(gè)新的單獨(dú)的任務(wù)棧佑力,這個(gè)Activity的實(shí)例獨(dú)自運(yùn)行在棧內(nèi)。
TaskAffinity
TaskAffinity用于標(biāo)識(shí)一個(gè)任務(wù)棧筋遭,通常我們并沒(méi)有在AndroidManifest文件中看到此參數(shù)的聲明打颤,因?yàn)閼?yīng)用下的所有Activity的任務(wù)棧名字默認(rèn)為包名暴拄。
這個(gè)參數(shù)一般和SingleTask模式更配,一起配對(duì)使用效果更佳哦编饺,用于標(biāo)識(shí)這種啟動(dòng)模式的Activity應(yīng)該運(yùn)行于哪個(gè)任務(wù)棧中乖篷。
使用
- AndroidManifest文件中聲明
<activity
android:name=".XyActivity"
android:launchMode="singleTask"/>
- 代碼動(dòng)態(tài)設(shè)置
Intent intent = new Intent(xxx.this, XXX.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
在模擬測(cè)試的過(guò)程中,可以使用 adb shell dumpsys activities
命令查看任務(wù)棧及其中的activity實(shí)例以驗(yàn)證自己的猜想透且。