別人我不知道,反正對(duì)我來說,這種知識(shí)點(diǎn)就像xx生命周期,每次都看,但看完就忘。
今天就花點(diǎn)時(shí)間寫下來,希望能記得長(zhǎng)久一點(diǎn)。
目前常見的啟動(dòng)模式有四種:
1. standard
標(biāo)準(zhǔn)模式,是系統(tǒng)的默認(rèn)模式,也是“最沒有個(gè)性”的啟動(dòng)模式。每次啟動(dòng)一個(gè)activity都會(huì)重新創(chuàng)建一個(gè)新的實(shí)例,并且,“誰(shuí)需要它,它就跟誰(shuí)跑”。怎么講?A是standard模式,B啟動(dòng)A,二話不說,A就會(huì)new一個(gè)實(shí)例跑到B所在的棧里。
2. singleTop
棧頂復(fù)用,一個(gè)“比較環(huán)?!钡膯?dòng)模式。假如現(xiàn)在棧內(nèi)是ABCD,A在下,D在上,D啟動(dòng)模式是singleTop。如果再次啟動(dòng)D,D是不會(huì)重新創(chuàng)建的,所以,棧內(nèi)情況仍會(huì)是ABCD。但是D的onNewIntent方法會(huì)被調(diào)用,通過參數(shù)可以得到當(dāng)前請(qǐng)求的信息。
3. singleTask
棧內(nèi)復(fù)用,一個(gè)“對(duì)周圍環(huán)境很講究”的啟動(dòng)模式。一個(gè)activity的“周圍環(huán)境”是什么?棧唄!其實(shí)翻譯成“棧內(nèi)復(fù)用”不太利于理解,因?yàn)閟ingleTask其實(shí)是這樣的:對(duì)于一個(gè)activity來說,有符合要求的棧,我才復(fù)用;如果沒有,那就新建一個(gè)符合要求的棧,然后我愿意才住進(jìn)去。
舉個(gè)栗子:
A在棧底,D是singleTask的
- Stack1內(nèi)有ABC。D要求棧是Stack2。要啟動(dòng)D,手頭上沒有Stack2,怎么辦?新建一個(gè)Stack2,然后把D的實(shí)例放進(jìn)去。
- Stack1內(nèi)有ABCD,并且,D要求棧也是Stack1。啟動(dòng)D,系統(tǒng)并不會(huì)重新創(chuàng)建D實(shí)例,但D的onNewIntent會(huì)被回調(diào)。如果最開始Stack1中并沒有D,只有ABC,系統(tǒng)才會(huì)創(chuàng)建D的實(shí)例。
- Stack1內(nèi)有ADBC,D要求棧也是是Stack1。啟動(dòng)D,D的onNewIntent被回調(diào),棧內(nèi)變成AD。BC被clearTop了。
4. singleInstance
單實(shí)例模式,“不愿意跟別人合租”的模式。這是singleTask的加強(qiáng)版,除了具有singleTask所有的特性外,還加強(qiáng)了一點(diǎn),具有此模式的activity只能單獨(dú)地位于一個(gè)任務(wù)棧中。例如,Activity A是singleInstance的,A啟動(dòng)后,系統(tǒng)會(huì)為它單獨(dú)新建一個(gè)任務(wù)棧,A會(huì)獨(dú)自在這個(gè)新的任務(wù)棧中,后面的請(qǐng)求均不會(huì)創(chuàng)建新的A實(shí)例,除非這個(gè)棧被銷毀。
既然已經(jīng)到這了,不妨更進(jìn)一步。
<activity
android:allowTaskReparenting="true"
android:taskAffinity="xxx"
android:launchMode="singleTask"
android:name=".xxx.AbcActivity" />
上面在聊singleTask的時(shí)候說到一個(gè)概念——“符合要求的?!保降资裁礃拥臈2攀恰胺弦蟮臈!蹦??這得從一個(gè)參數(shù)說起,taskAffinity,它指定了一個(gè)activity所需要的任務(wù)棧的名字,默認(rèn)情況下activity所需任務(wù)棧的名字都是應(yīng)用的包名。
taskAffinity主要有兩大用處:
- 配合singleTask,不解釋。
- 配合 allowTaskReparenting
reparent,從字面上理解就是“重新指定父母”的意思。舉個(gè)栗子:
背景,Activity C,存在于應(yīng)用B中,allowTaskReparenting為true,taskAffinity為默認(rèn)值。
現(xiàn)象,應(yīng)用A啟動(dòng)應(yīng)用B的Activity C,按home鍵退回桌面,再點(diǎn)擊應(yīng)用B圖標(biāo),此時(shí)顯示的并不會(huì)是B的MainActivity,而是顯示Activity C。
原因,開始,C的確在A的任務(wù)棧內(nèi),但A的任務(wù)棧并不是符合C要求的任務(wù)?!猼askAffinity是應(yīng)用B包名的任務(wù)棧,C是“身在曹營(yíng)心在漢”的。應(yīng)用B一旦啟動(dòng),系統(tǒng)發(fā)現(xiàn)符合C要求的任務(wù)棧已經(jīng)創(chuàng)建,就做了一個(gè)reparent的操作——把C從A的棧轉(zhuǎn)移到B的棧中。