Activity啟動模式總結(jié)

初學Android時,對于啟動模式?jīng)]有任何概念,導致在項目中,可能某一個Activity多次被創(chuàng)建,要完全退出應用時,就需要多次按back鍵,并且發(fā)現(xiàn)有多個相同的Activity被移除,當時就有點感覺啟動模式自己還是有很多地方不了解。

我們每次啟動一個Activity時,會創(chuàng)建一個實例放入到一個任務(wù)棧中,系統(tǒng)默認情況下,多次啟動同一個Activity時,系統(tǒng)會創(chuàng)建多個實例,放入到一個任務(wù)棧中,一種后進先出的棧結(jié)構(gòu)。當按back鍵時,任務(wù)棧就會移除一個Activity實例,直至任務(wù)棧為空時,系統(tǒng)回收該任務(wù)棧,這個應用也就結(jié)束了。

四種啟動模式

standard, singleTop, singleTask, singleInstance

一、standard

系統(tǒng)默認的模式,每次創(chuàng)建一個Activity時,都會在棧中創(chuàng)建一個實例。也就是說不管棧中這個實例是否存在都一定會創(chuàng)建一個新的實例。
這個模式下,誰啟動了Activity,那這個Activity就運行在啟動它的那個Activity的任務(wù)棧中。

輸出日志

從StandardActivity啟動BStandardActivity,然后BStandardActivity在啟動一次自己,我們可以看到它們的taskID都是206,也就是說都處于同一個任務(wù)棧中,這也就和前文所說的一樣, 誰啟動了Activity,那這個Activity就運行在啟動它的那個Activity的任務(wù)棧中

二、singleTop

棧頂復用模式。該模式下,如果新的Activity已經(jīng)位于棧頂,那么則不會創(chuàng)建新的實例,同時會回調(diào)onNewIntent()方法,**需要注意,這時這個新的Activity的onCreate(),onStart()不會被調(diào)用,因為它并沒有發(fā)生。但是若新的Activity沒有位于棧頂,還是會創(chuàng)建一個新的實例。

singleTop輸出日志

測試代碼中Activity的啟動順序SingleTopActivity--->SingleTopActivity--->OtherSingleTopActivity--->SingleTopActivity
我們可以看到第二次啟動SingleTopActivity時,沒有調(diào)用onCreate(),而是調(diào)用了onNewIntent(),兩次的hashcode都是一樣的,說明沒有創(chuàng)建新的實例。當從OtherSingleTopActivity中啟動SingleTopActivity時,由于SingleTopActivity已經(jīng)不再棧頂,所以需要重新創(chuàng)建一個實例,hashcode就與之前的不一樣了。

需要注意,除了standard模式是系統(tǒng)默認,其余三個啟動模式都需要在注冊文件表中手動聲明

<activity android:name=".singleTop.SingleTopActivity"
android:launchMode="singleTop"
android:taskAffinity="com.zhu.testlaunchmode.singleTop"></activity>```

######注意
standard和singleTop模式下,都是在原任務(wù)棧中創(chuàng)建實例,即使指定了taskAffinity屬性,也不會啟動新的task。我們可以從輸出日志看到,taskId都是相同,即使指定了不同的taskAffinity。

**taskAffinity**可以理解為任務(wù)相關(guān)性
> - 這個參數(shù)標識了一個Activity所需任務(wù)棧的名字,默認情況下,所有Activity所需的任務(wù)棧的名字為應用的包名
- 我們可以單獨指定每一個Activity的taskAffinity屬性覆蓋默認值
-  一個任務(wù)的affinity決定于這個任務(wù)的根activity(root activity)的taskAffinity
- 在概念上,具有相同的affinity的activity(即設(shè)置了相同taskAffinity屬性的activity)屬于同一個任務(wù)
- 為一個activity的taskAffinity設(shè)置一個空字符串,表明這個activity不屬于任何task

上述引用《Android開發(fā)藝術(shù)探索》

#####三、singleTask
棧內(nèi)復用模式。**這是一種單例模式**,如果任務(wù)棧中有新Activity的實例,則不會創(chuàng)建,同時回調(diào)```onNewIntent()```方法。具體來講,若新的Activity所處的任務(wù)棧的不存在,則創(chuàng)建一個新的任務(wù)棧,并創(chuàng)建實例壓入棧中。   若存在Activity所需要的任務(wù)棧,當前棧中若不存在該Activity的實例則創(chuàng)建,否則將存在的實例放在棧頂并調(diào)用```onNewIntent()```

舉幾個例子:
1. 任務(wù)棧t1內(nèi)有實例ABC,此時Activity D以singleTask模式啟動,且它所需要的任務(wù)棧為t2,由于t2不存在,所以系統(tǒng)先創(chuàng)建一個新的任務(wù)棧t2,并創(chuàng)建實例D壓入t2中
2. D的任務(wù)棧為t1,其余情況如上,因為任務(wù)棧t1已經(jīng)存在,且棧中不存在D的實例,則創(chuàng)建一個新的實例壓入棧t1中
3. D的任務(wù)棧為t1,且t1中有實例ABDC,由于棧中存在D的實例,則把D調(diào)到棧頂,并調(diào)用```onNewIntent()```方法。需要注意的是,singleTask默認具有clearTop的效果,會將位于D之上的實例出棧,最后任務(wù)棧t1中,存在實例ABD。

![singleTask](http://upload-images.jianshu.io/upload_images/1944426-88564b26aed6a315.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

測試程序中Activity啟動順序:SingleTaskActivity-->SingleTaskActivity-->OtherSingleTaskActivity-->TaskActivity-->SingleTaskActivity

其中SingleTaskActivity和OtherSingleTaskActivity使用默認的任務(wù)棧,TaskActivity使用新的任務(wù)棧。

我們通過輸出日志可以看到當最后啟動SingleTaskActivity時,由于任務(wù)棧中它不是處于棧頂,則OtherSingleTaskActivity需要出棧,可以看到調(diào)用了```onDestroy()```,在調(diào)用SingleTaskActivity的```onNewIntent()```方法。

#####四、singleInstance
單實例模式,這是一個加強的singleTask模式。Activity獨占一個任務(wù)棧,就它一個,其他后續(xù)的請求均不會創(chuàng)建新的Activity,除非該任務(wù)棧被銷毀。

![singleInstance](http://upload-images.jianshu.io/upload_images/1944426-63d1c512c77e8f19.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

啟動順序:MainActivity-->SingleInstanceActivity-->SingleInstanceActivity

通過日志我們看到即使taskAffinity屬性一致,但設(shè)置了singleInstance模式還是會創(chuàng)建一個新的任務(wù)棧

**參考文章**
[Android Activity啟動模式的功能驗證 ](http://blog.csdn.net/sbsujjbcy/article/details/49360615)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容