??默認情況下级遭,當(dāng)我們多次啟動同一個Activity的時候,就會創(chuàng)建多個Activity實例迅腔,并把他們按照先進后出的順序放入同一個任務(wù)棧中装畅,當(dāng)我們返回的時候,就需要逐一退出各個實例沧烈。操作不便掠兄,并且多個實例也會造成內(nèi)存占用,影響性能锌雀。為避免這種情況蚂夕,Android提供了4種的啟動模式,來應(yīng)對各種復(fù)雜的啟動場景腋逆。
一婿牍、啟動模式分析
Activity的四種啟動模式如下:
1. Standard(default默認)標(biāo)準(zhǔn)默認模式
說明::允許多個實例存在,也允許多個實例重疊存在惩歉。每次啟動activity都會重新創(chuàng)建一個新的實例添加到任務(wù)棧中等脂。
生命周期::每次啟動都是新的實例,生命周期都會重新執(zhí)行撑蚌。
任務(wù)棧信息:每次開啟后在任務(wù)棧中都會開啟添加新的實例
從圖中可以看出開啟4次任務(wù)棧中有4個實例上遥,并且都在同一個任務(wù)棧中
2. SingleTop棧頂復(fù)用模式
說明:允許多個實例存在,但不允許多個實例重疊存在争涌。例如:如果一個singleTop啟動的實例存在棧頂粉楚,那么再次啟動,就不會創(chuàng)建新的實例亮垫,而是調(diào)用onNewIntent()方法服用當(dāng)前實例模软。
生命周期:分為兩種情況:
-
要創(chuàng)建的Activity實例不在棧頂,會重新創(chuàng)建新的實例饮潦,生命周期會重新執(zhí)行
任務(wù)棧信息:多個實例共存任務(wù)棧中燃异。
-
新創(chuàng)建的實例 棧頂復(fù)用是不會重新執(zhí)行生命周期,會執(zhí)行onNewIntent()更新參數(shù)
任務(wù)棧信息:棧頂只會存在一個singleTop模式activity继蜡,重新打開復(fù)用原來的
3. SingleTask棧內(nèi)復(fù)用模式
說明:不允許多個實例存在特铝,不允許多個實例堆疊存在暑中。每次啟動都會判斷任務(wù)棧中是否存在當(dāng)前的實例,如果存在則會調(diào)用onNewIntent()方法復(fù)用當(dāng)前實例鲫剿,并且清空當(dāng)前實例在任務(wù)棧之上的所有實例鳄逾。
生命周期:創(chuàng)建新的實例會執(zhí)行全部生命周期,如果棧內(nèi)已有實例灵莲,重新打開不會執(zhí)行全部生命周期雕凹,會執(zhí)行onNewIntent()更新參數(shù),
任務(wù)棧信息:棧內(nèi)復(fù)用政冻,如果已經(jīng)存在實例枚抵,不會重新創(chuàng)建,會復(fù)用之前實例明场,并且會清空同一個任務(wù)棧中的所有實例(關(guān)閉了中間開啟的singleTopActivity)汽摹。
4. SingleInstance單實例模式
說明:只存在一個實例,并且在單的任務(wù)棧中苦锨,并且這個任務(wù)棧有且僅有當(dāng)前一個實例存在逼泣。
生命周期:只會存在一個實例,如果存在不會創(chuàng)建只會會執(zhí)行onNewIntent()復(fù)用當(dāng)前實例舟舒。
任務(wù)棧信息:該實例存在的任務(wù)棧有且僅有一個當(dāng)前實例
notes
注意onNewIntent()方法中不能使用getIntent()獲取新傳入的數(shù)據(jù)拉庶,如果要使用先使用setIntent(intent)設(shè)置后使用;
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.e(TAG,"oNewIntent, open : "+TAG);
setIntent(intent);
}
二秃励、設(shè)定任務(wù)棧名稱后的啟動模式詳解
在清單文件中單獨設(shè)置任務(wù)棧名稱氏仗,
<activity
android:name=".SingleTaskActivity"
android:taskAffinity="test."
android:launchMode="singleTask" />
那么啟動的會在新的任務(wù)棧中,新的任務(wù)棧中啟動activity情況如下:
以下分析過程中中將SingleTaskActivity的任務(wù)棧名稱設(shè)置為test.
-
啟動standard模式的會在當(dāng)前存在的任務(wù)棧中啟動夺鲜。
-
在SingleInstance實例中啟動standar的模式,會選擇默認任務(wù)棧中創(chuàng)建實例币励。
-
啟動singTop任務(wù)棧床佳,仍在默認的任務(wù)棧中。
啟動singleTask榄审,同正常情況一樣。
啟動SingleInstance同正常情況一樣杆麸,任何情況下都是一個單的任務(wù)棧搁进,即使指定相同的任務(wù)棧名稱也不在同一個任務(wù)棧中。
結(jié)論:
- standard模式中昔头,會在當(dāng)前的任務(wù)棧中啟動新的實例饼问,如果當(dāng)前任務(wù)棧中不能創(chuàng)建(例如:當(dāng)前為SingleInstance)那么就會在默認的任務(wù)棧中創(chuàng)建實例。
- singleTop揭斧、singleTask如果沒有單獨指定任務(wù)棧名稱莱革,都會在默認的任務(wù)棧中啟動峻堰。即使在新的任務(wù)棧中啟動也不會在新的任務(wù)棧中創(chuàng)建實例。
- SingleInstance任何情況都在一個單獨的任務(wù)棧中盅视,并且有且僅有一個實例捐名。
三、不同任務(wù)棧中后退邏輯
- 在按返回鍵后退時闹击,會將當(dāng)前的任務(wù)棧中的activity全部退出后镶蹋,再依次退出后續(xù)的任務(wù)棧中的activity。
同上以下分析過程中將SingleTaskActivity的任務(wù)棧名稱設(shè)置為test.
實例中我們設(shè)定DefaultActivity為A ,SingleTopActivity為B赏半,具有單獨任務(wù)棧名稱的singleTaskActivity為C贺归,SingleInstanceActivity為D,
啟動順序如下:
A-->B-->A-->C-->A(295在前臺294在后臺)
此時存在兩個任務(wù)棧分別為:
1. ID295為singleTask所在任務(wù)棧其中順序為C-->A,
2. ID294默認任務(wù)棧順序A-->B-->A
此時再啟動D id為296(294 295任務(wù)棧進入后臺)
此時存在兩個任務(wù)棧分別為:
1. 前臺任務(wù)棧ID296只存在一個D
2. 后臺任務(wù)棧ID295為singleTask所在任務(wù)棧其中順序為C-->A断箫,
3. 后臺任務(wù)棧ID294默認任務(wù)棧順序A-->B-->A
此時在啟動B將默認任務(wù)椃骱ǎ回到前臺,存在三個任務(wù)棧
1. ID294前臺任務(wù)棧其中為A-->B-->A-->B前臺任務(wù)棧
2. ID296后臺任務(wù)棧其中只有一個D
3. ID295后臺任務(wù)棧順序C-->A
此時逐級返回順序為:
B-->A-->B-->A-->D-->A-->C
結(jié)論:在逐級返回中仲义,現(xiàn)將當(dāng)前activity實例所在的任務(wù)棧中的實例全部返回后婶熬,在按照任務(wù)棧的順序逐一退出各個任務(wù)棧中的activity實例。
以上實例代碼地址:https://github.com/Jhonzhou/LanuchModeDemo