Activity有四種加載模式:standard(默認(rèn))梅鹦, singleTop鹊奖, singleTask和 singleInstance。以下逐一舉例說明他們的區(qū)別:
Standard模式(默認(rèn))
我們平時(shí)直接創(chuàng)建的Activity都是這種模式的Activity,這種模式的Activity的特點(diǎn)是:只要你創(chuàng)建了Activity實(shí)例塞颁,一旦激活該Activity过咬,則會(huì)向任務(wù)棧中加入新創(chuàng)建的實(shí)例大渤,退
出Activity則會(huì)在任務(wù)棧中銷毀該實(shí)例。
standard:Activity的默認(rèn)加載方法掸绞,即使某個(gè)Activity在Task棧中已經(jīng)存在泵三,另一個(gè)activity通過Intent跳轉(zhuǎn)到該activity,同樣會(huì)新創(chuàng)建一個(gè)實(shí)例壓入棧中衔掸。例如:現(xiàn)在棧的情況為:A B C D烫幕,在D這個(gè)Activity中通過Intent跳轉(zhuǎn)到D,那么現(xiàn)在的棧情況為: A B C D D 敞映。此時(shí)如果棧頂?shù)腄通過Intent跳轉(zhuǎn)到B较曼,則棧情況為:A B C D D B。此時(shí)如果依次按返回鍵振愿,D D C B A將會(huì)依次彈出棧而顯示在界面上捷犹。
(1)standard:每次激活A(yù)ctivity時(shí)(startActivity),都創(chuàng)建Activity實(shí)例冕末,并放入任務(wù)棧萍歉;
SingleTop模式
這種模式會(huì)考慮當(dāng)前要激活的Activity實(shí)例在任務(wù)棧中是否正處于棧頂,如果處于棧頂則無需重新創(chuàng)建新的實(shí)例档桃,會(huì)重用已存在的實(shí)例枪孩,否則會(huì)在任務(wù)棧中創(chuàng)建新的實(shí)例。
singleTop:如果某個(gè)Activity的Launch mode設(shè)置成singleTop藻肄,那么當(dāng)該Activity位于棧頂?shù)臅r(shí)候销凑,再通過Intent跳轉(zhuǎn)到本身這個(gè)Activity,則將不會(huì)創(chuàng)建一個(gè)新的實(shí)例壓入棧中仅炊。例如:現(xiàn)在棧的情況為:A B C D斗幼。D的Launch mode設(shè)置成了singleTop,那么在D中啟動(dòng)Intent跳轉(zhuǎn)到D抚垄,那么將不會(huì)新創(chuàng)建一個(gè)D的實(shí)例壓入棧中蜕窿,此時(shí)棧的情況依然為:A B C D谋逻。但是如果此時(shí)B的模式也是singleTop,D跳轉(zhuǎn)到B桐经,那么則會(huì)新建一個(gè)B的實(shí)例壓入棧中毁兆,因?yàn)榇藭r(shí)B不是位于棧頂,此時(shí)棧的情況就變成了:A B C D B阴挣。
(2)singleTop:如果某個(gè)Activity自己激活自己气堕,即任務(wù)棧棧頂就是該Activity,則不需要?jiǎng)?chuàng)建畔咧,其余情況都要?jiǎng)?chuàng)建Activity實(shí)例茎芭;
SingleTask模式
如果任務(wù)棧中存在該模式的Activity實(shí)例,則把棧中該實(shí)例以上的Activity實(shí)例全部移除誓沸,調(diào)用該實(shí)例的newInstance()方法重用該Activity梅桩,使該實(shí)例處於棧頂位置,否則就重新創(chuàng)建一個(gè)新的Activity實(shí)例拜隧。
(3)singleTask:如果要激活的那個(gè)Activity在任務(wù)棧中存在該實(shí)例宿百,則不需要?jiǎng)?chuàng)建,只需要把此Activity放入棧頂洪添,并把該Activity以上的Activity實(shí)例都pop垦页;
singleTask:如果某個(gè)Activity是singleTask模式,那么Task棧中將會(huì)只有一個(gè)該Activity的實(shí)例干奢。例如:現(xiàn)在棧的情況為:A B C D痊焊。B的Launch mode為singleTask,此時(shí)D通過Intent跳轉(zhuǎn)到B律胀,則棧的情況變成了:A B宋光。而C和D被彈出銷毀了貌矿,也就是說位于B之上的實(shí)例都被銷毀了炭菌。
關(guān)于singleTask這個(gè)網(wǎng)上頗有爭(zhēng)議,google api說singTask模式只能啟動(dòng)一個(gè)task逛漫,且總是位于棧底黑低,這個(gè)也不是完全正確
分2種情況:
1、如果在同一個(gè)應(yīng)用(apk)中使用singleTask酌毡,剛不在棧底克握,對(duì)應(yīng)于下面的情況一
2、如果從不同應(yīng)用啟動(dòng)一個(gè)singleTask的activity枷踏,剛依賴于此activity所在的棧菩暗,如果之前沒有運(yùn)行過,則新建棧處于棧底旭蠕,如果有運(yùn)行過停团,則有可能不在棧底旷坦,對(duì)應(yīng)于情況二
情況一:如果在本程序中啟動(dòng)singleTask的activity:假設(shè)ActivityA是程序的入口,是默認(rèn)的模式(standard),ActivityB是singleTask 模式佑稠,由ActivityA啟動(dòng)秒梅,剛ActivityB不會(huì)位于棧底,不是根元素舌胶,不會(huì)啟動(dòng)新的task捆蜀,此種情況ActivityB會(huì)和ActivityA在一個(gè)棧中,位于ActivityA上面
情況二:如果ActivityB由另外一個(gè)程序啟動(dòng):假設(shè)apkA是情況一中的應(yīng)用幔嫂,apkB是另外一個(gè)測(cè)試程序辆它,在apkB中啟動(dòng)apkA中的ActivityB,再分兩種情況婉烟,如果ActivityB未啟動(dòng)過娩井,剛ActivityB會(huì)位于棧底,是根元素似袁,會(huì)啟動(dòng)新的task洞辣;如果ActivityB啟動(dòng)過,則ActivityB保持原來的位置不變昙衅,在棧底或者棧頂扬霜,移除掉ActivityB之上所有的activity(如果有),見下圖
此圖就是保存了activitY所在的棧的情況而涉,按返回鍵的時(shí)候著瓶,會(huì)首先依次移除掉activitY所在的棧的activity,然后才是activity2的
注意:singleTask模式的Activity不管是位于棧頂還是棧底啼县,再次運(yùn)行這個(gè)Activity時(shí)材原,都會(huì)destory掉它上面的Activity來保證整個(gè)棧中只有一個(gè)自己,切記切記
SingleInstance模式
當(dāng)該模式Activity實(shí)例在任務(wù)棧中創(chuàng)建后季眷,只要該實(shí)例還在任務(wù)棧中余蟹,即只要激活的是該類型的Activity,都會(huì)通過調(diào)用實(shí)例的newInstance()方法重用該Activity子刮,此時(shí)使用的都是同一個(gè)Activity實(shí)例威酒,它都會(huì)處于任務(wù)棧的棧頂。此模式一般用于加載較慢的挺峡,比較耗性能且不需要每次都重新創(chuàng)建的Activity葵孤。
singleInstance:將Activity壓入一個(gè)新建的任務(wù)棧中。例如:Task棧1的情況為:A B C橱赠。C通過Intent跳轉(zhuǎn)到D尤仍,而D的Launch mode為singleInstance,則將會(huì)新建一個(gè)Task棧2狭姨。此時(shí)Task棧1的情況還是為:A B C宰啦。Task棧2的情況為:D鲤嫡。此時(shí)屏幕界面顯示D的內(nèi)容,如果這時(shí)D又通過Intent跳轉(zhuǎn)到D绑莺,則Task棧2中也不會(huì)新建一個(gè)D的實(shí)例暖眼,所以兩個(gè)棧的情況也不會(huì)變化。而如果D跳轉(zhuǎn)到C纺裁,則棧1的情況變成了:A B C C诫肠,因?yàn)镃的Launch mode為standard,此時(shí)如果再按返回鍵欺缘,則棧1變成:A B C栋豫。也就是說現(xiàn)在界面還顯示C的內(nèi)容,不是D谚殊。
(4)singleInstance:如果應(yīng)用1的任務(wù)棧中創(chuàng)建了MainActivity實(shí)例丧鸯,如果應(yīng)用2也要激活MainActivity,則不需要?jiǎng)?chuàng)建嫩絮,兩應(yīng)用共享該Activity實(shí)例丛肢;