Activity為什么需要啟動(dòng)模式?在默認(rèn)情況下,當(dāng)多次去請(qǐng)求同一個(gè)Activity時(shí)候桑腮,系統(tǒng)會(huì)創(chuàng)建多個(gè)實(shí)例并把它一一放入到任務(wù)棧中,當(dāng)按下back鍵的時(shí)候蛉幸,Activity會(huì)一一回退破讨。因?yàn)椤皸!笔且环N后進(jìn)先出的結(jié)構(gòu)奕纫。當(dāng)Activity默認(rèn)啟動(dòng)時(shí)候提陶,系統(tǒng)會(huì)重復(fù)創(chuàng)建多個(gè)實(shí)例,為避免這種情況匹层,所以Android提供了四種啟動(dòng)模式來修改系統(tǒng)的默認(rèn)啟動(dòng)模式:standard,singleTop,singleTask,singleInstance隙笆。
1.standard,標(biāo)準(zhǔn)的啟動(dòng)模式升筏,即系統(tǒng)的默認(rèn)啟動(dòng)模式撑柔,每次啟動(dòng)都會(huì)創(chuàng)建一個(gè)實(shí)例,不管實(shí)例是否存在您访,創(chuàng)建的實(shí)例生命周期符合Activity正常的生命周期铅忿。典型的多實(shí)例體現(xiàn),一個(gè)任務(wù)棧中可以有多個(gè)實(shí)例灵汪,每個(gè)實(shí)例可以有不同的任務(wù)棧檀训。
舉例:Activity A 啟動(dòng)了ActivityB(standard模式),那么B會(huì)進(jìn)入到A棧中享言。
注:當(dāng)用ApplicationContext去啟動(dòng)standard的時(shí)候峻凫,會(huì)拋出異常:
這是由于ApplicationContex沒有所謂的任務(wù)棧,此時(shí)應(yīng)給待啟動(dòng)Activity添加FLAG_ACTIVITY_NEW_TASK標(biāo)記位览露,這樣Activity啟動(dòng)會(huì)為它創(chuàng)建一個(gè)新的任務(wù)棧荧琼,實(shí)際上采用了singleTask模式啟動(dòng)。
2.single Top:棧頂復(fù)用模式差牛。在這種模式下命锄,如果新Activity已經(jīng)位于任務(wù)棧棧頂,那么Activity不會(huì)被重新創(chuàng)建多糠,同時(shí)它的onNewIntent方法會(huì)被回調(diào)累舷,通過此方法可以取出當(dāng)前請(qǐng)求信息。
注:此模式下的Activity的onCreate夹孔,onStart不會(huì)被調(diào)用被盈。如果新Activity不在棧頂析孽,那么仍會(huì)重新創(chuàng)建。
舉例:棧內(nèi)有ActivityA,B,C,D只怎。A位于棧底袜瞬,D位與棧頂。如果D啟動(dòng)模式為standard,那么為ABCDD身堡。如果D啟動(dòng)模式為singleTop邓尤,那么為ABCD。
3.singleTask,棧內(nèi)復(fù)用模式贴谎。這是一種單例模式汞扎,在此模式下,只要Activity在一個(gè)棧中存在擅这,那么多次啟動(dòng)Activity都不會(huì)創(chuàng)建實(shí)例澈魄,和singleTop相同,系統(tǒng)也會(huì)回調(diào)onNewIntent仲翎。
舉例:ActivityA啟動(dòng)模式為singleTask痹扇,系統(tǒng)會(huì)尋找是否存在A想要的任務(wù)棧,如果不存在就重新創(chuàng)建一個(gè)棧溯香,然后創(chuàng)建A的實(shí)例并放入棧中鲫构。如果存在A所需的任務(wù)棧,則會(huì)去檢查棧中是否存在A的實(shí)例玫坛,如果存在结笨,系統(tǒng)調(diào)用A的onNewIntent,并把A調(diào)到棧頂昂秃。如果不存在實(shí)例禀梳,就創(chuàng)建實(shí)例并壓入棧中。
具體情況舉例:
(1)任務(wù)棧S1有ABC,D以singleTask模式請(qǐng)求啟動(dòng)后肠骆,D所需的任務(wù)棧為S2,S2不存在塞耕,系統(tǒng)會(huì)創(chuàng)建S2任務(wù)棧和D實(shí)例并入棧S2蚀腿。
(2)D所需的任務(wù)棧為S1,那么系統(tǒng)檢查S1里是否存在D實(shí)例扫外,如果不存在莉钙,創(chuàng)建D實(shí)例并入棧S1。
(3)與(2)同筛谚,但是D實(shí)例存在磁玉,調(diào)用D的onNewIntent,并且此時(shí)D位于S1任務(wù)棧的棧頂驾讲。同時(shí)由于singleTask默認(rèn)具有clearTop的效果蚊伞,D上面的Activity會(huì)全部出棧席赂,如ADBC會(huì)變成AD。
4.singleInstance:單實(shí)例模式时迫。singleTask模式的加強(qiáng)版颅停,不同的是,此模式的Activity只能單獨(dú)位于一個(gè)任務(wù)棧中掠拳。
舉例:
Activity A是singleInstance啟動(dòng)模式癞揉,那么A啟動(dòng)后,系統(tǒng)會(huì)為A單獨(dú)創(chuàng)建一個(gè)新的任務(wù)棧溺欧,A獨(dú)自在這個(gè)新任務(wù)棧中喊熟,且由于棧內(nèi)復(fù)用特性,后續(xù)請(qǐng)求都不會(huì)重新創(chuàng)建A姐刁,除非這個(gè)新任務(wù)棧被系統(tǒng)銷毀芥牌。
思考問題:假設(shè)有兩個(gè)任務(wù)棧,S1,S2龙填。S1是前臺(tái)任務(wù)棧AB,S2是后臺(tái)任務(wù)棧CD胳泉。CD啟動(dòng)模式均為singleTask,那么現(xiàn)在請(qǐng)求啟動(dòng)C和請(qǐng)求啟動(dòng)D有什么區(qū)別岩遗?
個(gè)人理解:如果請(qǐng)求D扇商,那么后臺(tái)任務(wù)切換到前臺(tái),那么后退列表變?yōu)锳BCD宿礁,如果請(qǐng)求C案铺,那么C會(huì)把D給清除掉(singleTask的clearTop的效果),那么后退列表就變成ABC梆靖。
什么是singleTask的所需任務(wù)棧呢控汉?
即一個(gè)參數(shù):Taskfinity(任務(wù)相關(guān)性),此參數(shù)標(biāo)識(shí)了一個(gè)Activity所需要任務(wù)棧的名字返吻,默認(rèn)情況下姑子,所有Activity所需任務(wù)棧都是包名。Activity也可以單獨(dú)指定Taskfinity屬性测僵,但是該屬性必須與包名不同街佑,否則指定無意義。Taskfinity必須和singleTask啟動(dòng)模式或者和allowTaskReparenting屬性配對(duì)使用捍靠,其他情況也無意義沐旨。任務(wù)棧分前臺(tái)任務(wù)棧和后臺(tái)任務(wù)棧。
當(dāng)Taskfinity和singleTask配對(duì)使用榨婆,它具有當(dāng)前該模式Activity目前任務(wù)棧的名字磁携,待啟動(dòng)的Activity會(huì)運(yùn)行在名字和Taskfinity相同的任務(wù)棧中。
當(dāng)Taskfinity和allowTaskReparenting結(jié)合使用良风,會(huì)產(chǎn)生特殊情況谊迄。當(dāng)應(yīng)用A啟動(dòng)了B的某個(gè)ActivityC后闷供,如果C的allowTaskReparenting屬性為true,那么當(dāng)應(yīng)用B啟動(dòng)后,C會(huì)直接從應(yīng)用A移動(dòng)到應(yīng)用B的任務(wù)棧中鳞上。通俗來說这吻,此時(shí)應(yīng)用B啟動(dòng)后并不會(huì)啟動(dòng)B的主Activity,而是重新顯示在A里已啟動(dòng)的C(此時(shí)C從A任務(wù)棧轉(zhuǎn)移到到B任務(wù)棧篙议,由于是A啟動(dòng)C,C只能在A任務(wù)棧唾糯,但是C又屬于B,而Taskfinity值又肯定不能和A相同(包名不允許相同)鬼贱,所以當(dāng)B啟動(dòng)后又會(huì)創(chuàng)建新任務(wù)棧移怯,這時(shí)系統(tǒng)會(huì)發(fā)現(xiàn)C的任務(wù)棧已經(jīng)被創(chuàng)建了,所以C會(huì)移動(dòng)到B任務(wù)棧)这难。
至此舟误,我也明白了工作中調(diào)用第三方app后(如地圖導(dǎo)航)返回后仍是自己APP的界面以及重新進(jìn)入第三方app直接顯示之前調(diào)用界面的原因。
指定Activity的啟動(dòng)模式有兩種姻乓,一種是通過AndroidMenifest為Activity指定啟動(dòng)模式:
另一種通過intent中設(shè)置標(biāo)志位來指定啟動(dòng)模式:
二者區(qū)別:
intent指定優(yōu)先級(jí)高于AndroidMenifest指定嵌溢,兩者若同時(shí)存在,以intent為準(zhǔn)蹋岩。
限定范圍不同:AndroidMenifest指定無法直接設(shè)定FLAG_ACTIVITY_CLEAR_TOP標(biāo)識(shí)赖草,而intent無法為Activity指定singleInstance模式。