Activity使我們在開發(fā)中最常用到的組件凡纳,除了坑爹的生命周期他的啟動模式也是很重要的一個知識點燥筷。
Activity 一共有四種啟動模式刁卜,分別為:standard蠢正,singleTop闯割,singleTask彻消,singleInstance。一下分別討論著四種啟動模式的異同和使用場景宙拉。
standard
standard是系統(tǒng)默認的啟動模式宾尚,他的特點是每次啟動Activity都會創(chuàng)建一個新的Activity實例。每個新的Activity既可以存在于同一個任務棧也可以存在于不同的任務棧下(任務棧接下來會淺談)谢澈,誰啟動了這個standard模式的Activity煌贴,這個Activity就是出現在誰的棧內(singleInstance下令做討論)。如果用ABCD的代表四個Activity的話我們啟動了順序A-B-C這個時候又啟動了B那么棧內就會有ABCB四個Activity實例锥忿。ABCD在下文中代表四個Activity
singleTop
該模式下分類討論牛郑,
①該Activity已經存在:
a.該Activity已經位于棧頂:這個Activity就不會被重新創(chuàng)建,并且會調用onNewIntent方法敬鬓。舉例說明淹朋,我們啟動了ABCD四個Acitivity笙各,這個時候D位于棧頂,并且D是singleTop模式础芍,這個時候在D內重新啟動D任務棧內結構仍為ABCD杈抢,但是這個時候D的onCreate,onStart不會被調用者甲,onNewIntent被系統(tǒng)調起春感,我們可以再onNewIntent里面處理相關的信息。
b.該Activity不在棧頂:直接舉例說明虏缸,C為singleTop模式,其他的為standar模式嫩实,棧內存在ABDC刽辙,C在棧頂,這個時候再去啟動D就會重新創(chuàng)建一個新的Activity甲献,棧內存在ABDCD五個Activity宰缤。
②該Activity不存在
會創(chuàng)建一個新的位于棧頂的Activity,其他同上晃洒。
singleTask
一個App不一定是只有一個任務棧干到死的慨灭,可能存在多個任務棧,而在singleTask模式的Activity只會存在一個棧內球及,分類討論如下:
①該Activity在所在的棧都不存在:
創(chuàng)建一個新的棧然后將新Activity壓入棧內氧骤。
②該Activity所在的任務棧存在:
a.棧在Activity不存在:創(chuàng)建新的Activity并壓入棧內。
b.棧在Activity也存在:
1.該Activity在棧頂:Activity喚起并調用onNewIntent吃引。
2.該Acitivity不在棧頂:該Activity被調至棧頂并調用onNewIntent筹陵。
注意:棧的結構是先進后出的,所謂的調至棧頂就是清空該Activity上面的Activity使用其暴露在頂部镊尺。(好黑暗/(ㄒoㄒ)/~~)
(上面提到的Acitivity所在的棧會在討論完這四種模式后討論)
好吧朦佩,顯然這個singleTask模式是為處女座準備的。
舉個栗子:棧S1存在ABC 庐氮,在C內啟動singleTask模式的D语稠,D所在的棧應該為S2,好了弄砍,開始套公式(敲黑板)仙畦,
如果S2不存在,創(chuàng)建S2输枯,并在S2內創(chuàng)建新的D议泵;
如果S2存在,里面已經有了EF就是沒有D桃熄,那么創(chuàng)建D掺涛,并壓入S2棧頂耿戚;
如果S2存在误窖,里面有了DEF,猥瑣的D蹲在正好棧底部厢汹,那么D上面的EF就會被趕出S2棧,使D出現在棧頂谐宙,并調用D的onNewIntent方法烫葬。
綜上所述:singleTask是一個任務棧內復用的模式。
PS:啟動一個新的任務棧的singleTaskActivity系統(tǒng)動畫會和standard模式下一鍵跳轉不一樣凡蜻。不知道是不是系統(tǒng)的問題搭综,還是Android對于任務棧就是這么定義的。
singleInstance
顧名思義划栓,單例模式...
這種模式下和上述的singleTask很接近兑巾,唯一不一樣的是,在singleTask模式下的Activity是允許大家住一間屋的忠荞,但是它有事的時候你們都得讓路蒋歌,它是不會重建的。而這個singleInstance模式的Activity簡直就是混蛋的孤家寡人委煤,它不允許它住的屋子里面有人...也就是說singleInstance自己擁有一個任務棧堂油,棧內只有他自己。
我們上面提到在standard之下跳轉碧绞,在哪個棧內跳轉就standard模式的Activity就會出現的誰的棧內府框,但是基于上面singleInstance的孤家寡人理論這兩個顯然是矛盾的,本著知行合一头遭,做一個實現寓免,新建ABC三個Activity,C為singleTask计维,A->B->C 然后繼續(xù)跳轉到A袜香,這個是時候back,會發(fā)現顯示了B鲫惶,并沒有顯示C蜈首,接著back會顯示A,再BACK顯示C欠母,在C就退出應用了欢策。而且在C相鄰Activity會明顯發(fā)現動畫不一樣。
這是我們看到的情況赏淌,接下來我們用 abd shell dumpsys activity
命令踩寇,找到輸出
TaskRecord{85124cb #1461 A=com.maomibox.myapplication U=0 StackId=1 sz=3}
Run #16: ActivityRecord{7733e23 u0 com.maomibox.myapplication/.A t1461}
TaskRecord{e348f76 #1462 A=com.maomibox.myapplication U=0 StackId=1 sz=1}
Run #15: ActivityRecord{6c5074a u0 com.maomibox.myapplication/.C t1462}
TaskRecord{85124cb #1461 A=com.maomibox.myapplication U=0 StackId=1 sz=3}
Run #14: ActivityRecord{8047354 u0 com.maomibox.myapplication/.B t1461}
Run #13: ActivityRecord{9e18691 u0 com.maomibox.myapplication/.A t1461}
會發(fā)現id為85124cb只有ABAAcitivity,C存在于 id為e348f76 的棧內六水,也就是說C所在的棧內是有他自己俺孙,A也并沒有像上文說的standard一樣出現在C所在的棧內辣卒。在棧85124cb全部退出后,執(zhí)行e348f76 棧的退出睛榄,最終退出應用荣茫。
啥是任務棧
上面提到了那么多任務棧,這個任務棧是啥场靴?
棧是一種先進后出的結構啡莉,任務棧就是存放Activity的地方,standard模式下只有一個任務棧旨剥,而在singleTask模式下并搭配上taskAffinity屬性則會新開一個任務棧咧欣,singleInstance自帶Buff,自己會創(chuàng)建一個任務棧泞边,如果在singleTask下不指定taskAffinity那么就相當于啥都沒做该押,還是在默認棧內。給activity指定任務棧如下
<activity android:name=".C"
android:launchMode="singleInstance"
android:taskAffinity="com.demo.c"/>
上文提到的“所在的椪笱瑁”就是這個com.demo.c,C就運行在這個棧內烟具。
taskAffinity屬性和signleTask啟動模式或者和allowTaskReparenting搭配才有用沒其他情況下毛用沒有(有待驗證)梢什。
Activity FLAGS
Activity的Flag很多,Intent.FLAG_ACTIVITY_ IDE會聯想出來很多朝聋,列舉幾個常用的如下:
FLAG_ACTIVITY_NEW_TASK
同singleTask
FLAG_ACTIVITY_SINGLE_TOP
同singleTop
FLAG_ACTIVITY_CLEAR_TOP
該FLAG下同FLAG_ACTIVITY_NEW_TASK搭配下和之前將的清光棧暴露Acitivity類似嗡午。
使用場景(本段來自互聯網)自己體會吧...
standard: 適合多個實例存在的情況,比如冀痕,發(fā)郵件頁面荔睹。
singleTop: 適合接收通知內容顯示頁面。例如言蛇,某些應用會為用戶推送一些消息通知僻他,當用戶從任務欄中進入查看消息內容界面時,如果設置為singleTop時腊尚,這樣每次行為都使用同一個實例吨拗,用戶點擊返回時不會存在多個消息頁面的情況。
singleTask: 適合使用在一個程序的主界面婿斥。
singleInstance: 使用較少劝篷,比如一些launchAPP可能會使用到。