這幾天時間比較充裕捧灰,多寫幾篇统锤。今天來寫一下activity啟動模式饲窿。在昨天已經(jīng)說過了四種luncher的內(nèi)容焕蹄,下面來用代碼熟悉它們具體是怎么實(shí)現(xiàn)的。
standard
standard 是活動默認(rèn)的啟動模式鸦泳,在不進(jìn)行顯式指定的情況下永品,所有活動都會自動使用這種啟動模式鼎姐。因此,到目前為止我們寫過的所有活動都是使用的 standard 模式炕桨。經(jīng)過上一節(jié)的學(xué)習(xí)献宫,你已經(jīng)知道了 Android 是使用返回棧來管理活動的,在 standard 模式(即默認(rèn)情況)下涉瘾,每當(dāng)啟動一個新的活動,它就會在返回棧中入棧肴甸,并處于棧頂?shù)奈恢们舭汀τ谑褂?standard 模式的活動彤叉,系統(tǒng)不會在乎這個活動是否已經(jīng)在返回棧中存在,每次啟動都會創(chuàng)建該活動的一個新的實(shí)例浮庐。
@Override
protected voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
Log.v("lixinlalal","FirstActivity");
Button button=(Button)findViewById(R.id.button);
button.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(View v) {
Intent intent =newIntent(FirstActivity.this,FirstActivity.class);
startActivity(intent);
寫的demo中我們設(shè)置了一個按鍵柬焕,用于啟動一個活動斑举,點(diǎn)擊button以后讓它啟動自己這個頁面,會發(fā)現(xiàn)你每點(diǎn)擊一次button璧坟,頁面會刷新一下赎懦,生成一個新的FirstActivity励两,從log中也可以看到
我們點(diǎn)擊了3次,系統(tǒng)生成了3個返回棧的實(shí)例存放在返回棧當(dāng)中工三,點(diǎn)擊返回俭正,會回退到前一個返回棧實(shí)例對應(yīng)的activity焙畔,需要返回4次才能退出這個程序。用圖形表現(xiàn)如下
singleTop
singleTop在啟動活動時如果發(fā)現(xiàn)返回棧的棧頂已經(jīng)是該活動儿惫,則認(rèn)為可以直接使用它肾请,不會再創(chuàng)建新的活動實(shí)例。
在AndroidManifest的活動屬性設(shè)置那里添加紅線部分的代碼隔显,表示activity的啟動模式設(shè)定為singletop,運(yùn)行代碼括眠。
不管點(diǎn)擊多少次都不會再次調(diào)用FirstActivity的onCreate方法倍权,也就是說singleTop模式啟動活動時如果發(fā)現(xiàn)返回棧的棧頂已經(jīng)是該活動薄声,則直接使用它,不會重建一個返回棧的實(shí)例生年,從手機(jī)端的反應(yīng)的就是點(diǎn)擊button以后不會又刷新頁面的動畫廓奕,且點(diǎn)擊退出只需要點(diǎn)擊一次桌粉。
下面再添加一個activity試一下
代碼在上面铃肯,F(xiàn)irstActivity的button點(diǎn)擊后后啟動SecondActivity传蹈,SecondActivity頁面的button2會啟動FirstActivity惦界。
進(jìn)入app以后多次點(diǎn)擊button打印的log如上圖。第一次點(diǎn)擊FirstActivity的button會先檢查棧頂是不是SecondActivity漂彤,此時棧頂是FirstActivity,會生成一個新的返回棧實(shí)例立润,存放SecondActivity桑腮;在SecondActivity點(diǎn)擊button蛉幸,會檢查棧頂是不是FirstActivity,此時棧頂是SecondActivity添忘,也會重新生成一個棧頂實(shí)例若锁,后面的點(diǎn)擊事件同理又固。點(diǎn)擊返回需要返回6次才能退出程序。
singleTask
singleTop 模式可以很好地解決重復(fù)創(chuàng)建棧頂活動的問題乏冀,但如果該活動并沒有處于棧頂?shù)奈恢昧韭伲€是可能會創(chuàng)建多個活動實(shí)例的识虚。為了讓某個活動在整個應(yīng)用程序的上下文中只存在一個實(shí)例就要借助 singleTask 模式來實(shí)現(xiàn)了。當(dāng)活動的啟動模式指定為 singleTask蔚晨,每次啟動該活動時系統(tǒng)首先會在返回棧中檢查是否存在該活動的實(shí)例铭腕,如果發(fā)現(xiàn)已經(jīng)存在則直接使用該實(shí)例多糠,并把在這個活動之上的所有活動統(tǒng)統(tǒng)出棧,如果沒有發(fā)現(xiàn)就會創(chuàng)建一個新的活動實(shí)例笋粟。
修改后的代碼如上面所示害捕,F(xiàn)irstActivity會啟動SecondActivity尝盼,SecondActivity會啟動FirstActivity,看將啟動模式變更為singleTask之后兩個活動之間是調(diào)用的onCreate方法重新實(shí)例化一個返回棧對象裁赠,還是調(diào)用onRestart方法重新調(diào)回之前的一個對象赴精,打印出的log如下圖
可以發(fā)現(xiàn)從SecondActivity啟動FirstActivity時調(diào)用的是onRestart方法蕾哟,并且把SecondActivity這個返回棧對象destory掉了谭确,重復(fù)操作,打印的log是相同的芬迄。說明singleTask模式在每次啟動該活動時昂秃,系統(tǒng)首先會在返回棧中檢查是否存在該活動的實(shí)例,如果發(fā)現(xiàn)已經(jīng)存在則直接使用該實(shí)例(onRestart)出皇,并把在這個活動之上的所有活動統(tǒng)統(tǒng)出棧(SecondActivity的onDestory方法),如果沒有發(fā)現(xiàn)就會創(chuàng)建一個新的活動實(shí)例(重新調(diào)用了SecondActivity的onCreate方法)荷科。
singleInstance?
不同于以上 3 種啟動模式畏浆,指定為 singleInstance 模式的活動會啟用一個新的返回棧,在每一次啟動頁面的時候會調(diào)用這個回棧來管理這個活動(其實(shí)如果 singleTask 模式指定了不同taskAffinity蜀涨,也會啟動一個新的返回棧來管理這個活動(其實(shí)如果 singleTask 模式指定了不同的 taskAffinity厚柳,也會啟動一個新的返回棧)。那么這樣做有什么意義呢便监?想象以下場景碳想,假設(shè)我們的程序中有一個活動是允許其他程序調(diào)用的,如果我們想實(shí)現(xiàn)其他程序和我們的程序可以共享這個活動的實(shí)例逊移,應(yīng)該如何實(shí)現(xiàn)呢胳泉?使用前面 3 種啟動模式肯定是做不到的觅够,因?yàn)槊總€應(yīng)用程序都會有自己的返回棧,同一個活動在不同的返回棧中入棧時必然是創(chuàng)建了新的實(shí)例钳吟。而使用 singleInstance 模式就可以解決這個問題红且,在這種模式下會有一個單獨(dú)的返回棧來管理這個活動涤姊,不管是哪個應(yīng)用程序來訪問這個活動,都共用的同一個返回棧壁酬,也就解決了共享活動實(shí)例的問題恨课。下面是demo代碼
FirstActivity啟動SecondActivity,SecondActivity啟動ThirdActivity纲辽。在SecondActivity的啟動模式中設(shè)置為singleInstance。log的打印情況如下
FirstActivity的Task_ID和ThirdActivity的Task_ID是一致的这吻。這說明SecondActivity的返回棧不同于另外兩個因块,它單獨(dú)存放在一個返回棧中。按下一次返回鍵
頁面直接回到了FirstActivity的頁面。再按返回鍵吩愧,回到了SecondActivity的頁面再按返回雁佳,則會退出程序。
原理呢:由于 FirstActivity 和 ThirdActivity 是存放在同一個返回棧里的堵腹,當(dāng)在 ThirdActivity的界面按下 Back 鍵星澳,ThirdActivity 會從返回棧中出棧,那么 FirstActivity 就成為了棧頂活動顯示在界面上腿堤,因此也就出現(xiàn)了從 ThirdActivity 直接返回到 FirstActivity 的情況如暖。然后在FirstActivity 界面再次按下 Back 鍵盒至,這時當(dāng)前的返回棧已經(jīng)空了,于是就顯示了另一個返回棧的棧頂活動樱衷,即 SecondActivity登淘。最后再次按下 Back 鍵黔州,這時所有返回棧都已經(jīng)空了,也就自然退出了程序牲蜀。這樣就可以實(shí)現(xiàn)我們?nèi)粘J褂玫腶pp中非正常頁面跳轉(zhuǎn)了绅这。
就先寫到這里吧~