初學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)建一個新的實例。

測試代碼中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。

測試程序中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ù)棧被銷毀。

啟動順序:MainActivity-->SingleInstanceActivity-->SingleInstanceActivity
通過日志我們看到即使taskAffinity屬性一致,但設(shè)置了singleInstance模式還是會創(chuàng)建一個新的任務(wù)棧
**參考文章**
[Android Activity啟動模式的功能驗證 ](http://blog.csdn.net/sbsujjbcy/article/details/49360615)