組件 -- Activity -- 啟動(dòng)模式

一絮识、Activity的LaunchMode

1. standard:標(biāo)準(zhǔn)模式,系統(tǒng)的默認(rèn)模式。

每次啟動(dòng)一個(gè)Activity都會(huì)重新創(chuàng)建一個(gè)新的實(shí)例(Activity的onCreate置媳、onStart于樟、onResume方法會(huì)被系統(tǒng)調(diào)用),不管這個(gè)實(shí)例是否已經(jīng)存在拇囊。在這種模式下迂曲,誰(shuí)啟動(dòng)了這個(gè)Activity,那么這個(gè)Activity就運(yùn)行在啟動(dòng)它的那個(gè)Activity所在的任務(wù)棧中寥袭。
比如路捧,同一應(yīng)用中,ActivityA啟動(dòng)了ActivityB(ActivityA是standard模式传黄,ActivityB是standard模式)杰扫,那么ActivityB就會(huì)進(jìn)入到ActivityA所在的任務(wù)棧中。
注意:當(dāng)我們用ApplictionContext去啟動(dòng)standard模式的Activity時(shí)膘掰,會(huì)報(bào)如下錯(cuò)誤:

android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

這是因?yàn)閟tandard模式的Activity默認(rèn)會(huì)進(jìn)入啟動(dòng)它的Activity所屬的任務(wù)棧中章姓,而非Activity類型的Context(比如ApplicationContext)并沒(méi)有所謂的任務(wù)棧,因此出問(wèn)題识埋。
解決這個(gè)問(wèn)題的方法是為待啟動(dòng)的Activity指定FLAG_ACTIVITY_NEW_TASK標(biāo)記位凡伊,這樣啟動(dòng)的時(shí)候就會(huì)創(chuàng)建一個(gè)新的任務(wù)棧,這個(gè)時(shí)候待啟動(dòng)的Activity實(shí)際上是以singleTask模式啟動(dòng)的窒舟。

2. singleTop:棧頂復(fù)用模式系忙。

在這種模式下,如果新Activity已經(jīng)位于任務(wù)棧的棧頂惠豺,那么此Activity不會(huì)被重新創(chuàng)建银还,同時(shí)它的onNewIntent方法會(huì)被回調(diào)(Activity的onPause、onNewIntent洁墙、onResume方法會(huì)被系統(tǒng)調(diào)用)蛹疯,通過(guò)此方法的參數(shù)我們可以取出當(dāng)前請(qǐng)求的信息。
比如热监,同一應(yīng)用中捺弦,ActivityA啟動(dòng)了ActivityB(ActivityA是standard模式,ActivityB是singleTop模式)狼纬,那么ActivityB就會(huì)進(jìn)入到ActivityA所在的任務(wù)棧中,這個(gè)時(shí)候ActivityB再啟動(dòng)ActivityB骂际,由于ActivityA所在的任務(wù)棧中棧頂為ActivityB疗琉,因此不會(huì)再重新創(chuàng)建ActivityB實(shí)例,而是會(huì)回調(diào)棧頂ActivityB的onNewIntent方法歉铝。

3. singleTask:棧內(nèi)復(fù)用模式盈简。

這是一種單實(shí)例模式,在這種模式下,系統(tǒng)首先會(huì)尋找是否存在Activity想要的任務(wù)棧柠贤,
(1)如果不存在Activity想要的任務(wù)棧香浩,就創(chuàng)建一個(gè)任務(wù)棧,然后創(chuàng)建Activity實(shí)例并放入到棧中臼勉。
(2)如果存在Activity想要的任務(wù)棧邻吭,這時(shí)要看任務(wù)棧是否存在Activity實(shí)例,
(2.1)如果不存在Activity實(shí)例宴霸,就創(chuàng)建Activity實(shí)例并放入到棧中囱晴。
(2.2)如果存在Activity實(shí)例,系統(tǒng)就會(huì)把Activity上面的其它Activity全部出棧瓢谢,并回調(diào)其onNewIntent方法(Activity的onNewIntent畸写、onRestart、onStart氓扛、onResume方法會(huì)被系統(tǒng)調(diào)用)枯芬。
比如,同一應(yīng)用中采郎,ActivityA啟動(dòng)了ActivityB(ActivityA是singleTask模式千所,ActivityB是standard模式),那么ActivityB就會(huì)進(jìn)入到ActivityA所在的任務(wù)棧中尉剩,這個(gè)時(shí)候ActivityB再啟動(dòng)ActivityA真慢,由于ActivityA所在的任務(wù)棧中已經(jīng)存在ActivityA實(shí)例,因此不會(huì)再重新創(chuàng)建ActivityA實(shí)例理茎,而是將棧內(nèi)ActivityA上面的ActivityB出棧黑界,并回調(diào)ActivityA的onNewIntent方法。

4.singleInstance:?jiǎn)螌?shí)例模式

在這種模式下皂林,Activity實(shí)例只能單獨(dú)地存在于一個(gè)任務(wù)棧中朗鸠,后續(xù)的請(qǐng)求均不會(huì)創(chuàng)建新的Activity實(shí)例,除非這個(gè)獨(dú)特的任務(wù)棧被系統(tǒng)銷毀了础倍。
比如烛占,同一應(yīng)用中,ActivityA啟動(dòng)了ActivityB(ActivityA是singleInstance模式沟启,ActivityB是standard模式)忆家,那么ActivityB就不會(huì)進(jìn)入到ActivityA所在的任務(wù)棧中,系統(tǒng)會(huì)創(chuàng)建新的任務(wù)棧德迹,并創(chuàng)建ActivityB實(shí)例放入到新棧中芽卿,而ActivityA仍然單獨(dú)地存在于其所在的任務(wù)棧中。

情景分析:

有兩個(gè)任務(wù)棧胳搞,前臺(tái)任務(wù)棧1有兩個(gè)Activity卸例,分別為ActivityA(棧底称杨,standard模式)、ActivityB(棧頂筷转,standard模式)姑原,后臺(tái)任務(wù)棧2有兩個(gè)Activity,分別為ActivityX(棧底呜舒,singleTask模式)锭汛、ActivityY(棧頂,singleTask模式)阴绢,分以下兩個(gè)情況:
情況1. ActivityB去啟動(dòng)ActivityY店乐,
整個(gè)任務(wù)棧2會(huì)被切換到前臺(tái),即任務(wù)棧2顯示在任務(wù)棧1上面呻袭。連續(xù)按返回鍵則出棧順序?yàn)椋篈ctivityY眨八,ActivityX,ActivityB左电,ActivityA廉侧。
情況2. ActivityB去啟動(dòng)ActivityX,
任務(wù)棧2中ActivityY出棧篓足,剩下的任務(wù)棧全部被切換到前臺(tái)段誊,即任務(wù)棧2顯示在任務(wù)棧1上面。連續(xù)按返回鍵則出棧順序?yàn)椋篈ctivityX栈拖,ActivityB连舍,ActivityA。

TaskAffinity屬性:

可翻譯為任務(wù)相關(guān)性涩哟,這個(gè)參數(shù)標(biāo)識(shí)了一個(gè)Activity所需要的任務(wù)棧名字索赏,默認(rèn)情況下,所有Activity所需的任務(wù)棧名字為應(yīng)用的包名贴彼,當(dāng)然潜腻,我們可以為每一個(gè)Activity都單獨(dú)指定TaskAffinity屬性。
TaskAffinity屬性主要和singleTask模式和allowTaskReparenting屬性配合使用器仗,在其他情況下沒(méi)有意義融涣。分以下兩個(gè)情況:
情況1. 當(dāng)TaskAffinity屬性和singleTask模式配合使用時(shí),
待啟動(dòng)Activity會(huì)運(yùn)行在名字和TaskAffinity相同的任務(wù)棧中精钮。
情況2. 當(dāng)TaskAffinity屬性和allowTaskReparenting屬性配合使用時(shí)威鹿,
它允許allowTaskReparenting屬性為true的Activity重新回到名字和TaskAffinity相同的任務(wù)棧中。
比如轨香,應(yīng)用1有一個(gè)Activity(非主Activity)忽你,為ActivityA(standard模式,TaskAffinity屬性為應(yīng)用1包名)弹沽,應(yīng)用2有一個(gè)Activity(非主Activity)檀夹,為ActivityX(standard模式,TaskAffinity屬性為應(yīng)用2包名策橘,allowTaskReparenting屬性為true)炸渡。首先ActivityA啟動(dòng)ActivityX,系統(tǒng)會(huì)創(chuàng)建ActivityX實(shí)例并放到ActivityA實(shí)例所在的任務(wù)棧中丽已;然后按下home鍵蚌堵,在launch界面啟動(dòng)應(yīng)用2,這時(shí)顯示在前臺(tái)的是ActivityX而不是主Activity沛婴,即ActivityX從名字為應(yīng)用1包名的任務(wù)棧中轉(zhuǎn)移到了名字為應(yīng)用2包名的任務(wù)棧中吼畏。

二、Activity的Flags

FLAG_ACTIVITY_NEW_TASK

這個(gè)標(biāo)記位的作用是為Activity指定"singleTask"啟動(dòng)模式嘁灯。

FLAG_ACTIVITY_SINGLE_TOP

這個(gè)標(biāo)記位的作用是為Activity指定"singleTop"啟動(dòng)模式泻蚊。

FLAG_ACTIVITY_CLEAR_TOP

具有此標(biāo)記位的Activity,當(dāng)它啟動(dòng)時(shí)丑婿,在同一個(gè)任務(wù)棧中所有位于它上面的Activity都要出棧性雄,至于Activity自身是否出棧跟其啟動(dòng)模式有關(guān)系。
比如羹奉,同一應(yīng)用中秒旋,ActivityA啟動(dòng)了ActivityB(ActivityB是standard模式),那么ActivityB就會(huì)進(jìn)入到ActivityA所在的任務(wù)棧中诀拭,這時(shí)ActivityB啟動(dòng)ActivityA迁筛,并設(shè)置標(biāo)記位FLAG_ACTIVITY_CLEAR_TOP,分以下兩個(gè)情況:
情況1. 如果ActivityA是singleTask模式耕挨,
ActivityB會(huì)出棧细卧,ActivityA會(huì)回調(diào)onNewIntent方法(Activity的onNewIntent、onRestart俗孝、onStart酒甸、onResume方法會(huì)被系統(tǒng)調(diào)用)
情況2. 如果ActivityA是standard模式赋铝,
ActivityB跟ActivityA都會(huì)出棧插勤,系統(tǒng)會(huì)重新創(chuàng)建ActivityA實(shí)例并放入棧中(Activity的onCreate、onStart革骨、onResume方法會(huì)被系統(tǒng)調(diào)用)农尖。

FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS(測(cè)試無(wú)效果)

具有這個(gè)標(biāo)記的Activity不會(huì)出現(xiàn)在歷史Activity的列表中,等同于android:excludeFromRecents="true"良哲。

三盛卡、指定啟動(dòng)模式

方式1:通過(guò)AndroidManifest指定

<activity android:name=".ActivityA"
    android:launchMode="singleTask"/>

方式2:通過(guò)Intent設(shè)置標(biāo)志位指定

Intent intent = new Intent(MainActivity.this, ActivityA.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

兩種方式的區(qū)別:

以上兩種方式都可以為Activity指定啟動(dòng)模式,但是在優(yōu)先級(jí)上筑凫,方式2的優(yōu)先級(jí)要高于方式1滑沧,當(dāng)兩種方式同時(shí)存在時(shí)并村,以方式2為準(zhǔn)。

四滓技、查看任務(wù)棧

//命令
adb shell dumpsys activity

//log
ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)

Running activities (most recent first):
  TaskRecord{33bfcd5 #2209 A=com.tomorrow.androidtest8 U=0 sz=1}
    Run #3: ActivityRecord{23fb6ed u0 com.tomorrow.androidtest8/.ActivityY t2209}
  TaskRecord{951bcea #2208 A=com.tomorrow.androidtest7 U=0 sz=3}
    Run #2: ActivityRecord{237f43b u0 com.tomorrow.androidtest8/.ActivityX t2208}
    Run #1: ActivityRecord{6e79040 u0 com.tomorrow.androidtest7/.ActivityA t2208}
    Run #0: ActivityRecord{5354310 u0 com.tomorrow.androidtest7/.MainActivity t2208}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末哩牍,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子令漂,更是在濱河造成了極大的恐慌膝昆,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叠必,死亡現(xiàn)場(chǎng)離奇詭異荚孵,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)纬朝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén)收叶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人共苛,你說(shuō)我怎么就攤上這事滔驾。” “怎么了俄讹?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵哆致,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我患膛,道長(zhǎng)摊阀,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任踪蹬,我火速辦了婚禮胞此,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘跃捣。我一直安慰自己漱牵,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開(kāi)白布疚漆。 她就那樣靜靜地躺著酣胀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪娶聘。 梳的紋絲不亂的頭發(fā)上闻镶,一...
    開(kāi)封第一講書(shū)人閱讀 51,287評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音丸升,去河邊找鬼铆农。 笑死,一個(gè)胖子當(dāng)著我的面吹牛狡耻,可吹牛的內(nèi)容都是我干的墩剖。 我是一名探鬼主播猴凹,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼岭皂!你這毒婦竟也來(lái)了精堕?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蒲障,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后瘫证,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體揉阎,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年背捌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了毙籽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡毡庆,死狀恐怖坑赡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情么抗,我是刑警寧澤毅否,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站蝇刀,受9級(jí)特大地震影響螟加,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吞琐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一捆探、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧站粟,春花似錦黍图、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至切诀,卻和暖如春恰起,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背趾牧。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工检盼, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人翘单。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓吨枉,卻偏偏與公主長(zhǎng)得像蹦渣,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子貌亭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354