一襟雷、TaskAffinity
TaskAffinity翻譯過(guò)來(lái)就是“任務(wù)相關(guān)性”姿搜,它表示了一個(gè)Activity所需要的任務(wù)棧的名字蛹找。
在平時(shí)的開(kāi)發(fā)中肚豺,我們一般很少使用到TaskAffinity這個(gè)屬性签赃,也沒(méi)有聽(tīng)說(shuō)過(guò)Activity需要什么任務(wù)棧之類(lèi)的谷异。其實(shí)分尸,在默認(rèn)情況下,如果不指定TaskAffinity屬性歹嘹,Activity所需任務(wù)棧的名字就是應(yīng)用的名字箩绍。
1、默認(rèn)的任務(wù)棧
我們?cè)谝粋€(gè)應(yīng)用中啟動(dòng)三個(gè)Activity尺上,然后在Terminal中執(zhí)行adb shell dumpsys activity命令材蛛,結(jié)果如下:
Running activities (most recent first):
TaskRecord{853dee #503 A=com.hwldzh.myapplication U=0 StackId=1 sz=3}
Run #4: ActivityRecord{c1a608e u0 com.hwldzh.myapplication/.ThirdActivity t503}
Run #3: ActivityRecord{7289178 u0 com.hwldzh.myapplication/.SecondActivity t503}
Run #2: ActivityRecord{8539f65 u0 com.hwldzh.myapplication/.MainActivity t503}
可以看到,啟動(dòng)的三個(gè)Activity都位于“com.hwldzh.application”這個(gè)任務(wù)棧中怎抛,而這個(gè)名字就是我們這個(gè)應(yīng)用的包名卑吭。
2、TaskAffinity初登場(chǎng)
接下來(lái)马绝,我們給ThirdActivity加上TaskAffinity的屬性豆赏,即在Manifest中的聲明如下:
<activity
android:name=".ThirdActivity"
android:taskAffinity="com.hwldzh.ThirdActivity"/>
我們繼續(xù)執(zhí)行在Terminal中執(zhí)行adb shell dumpsys activity命令,看ThirdActivity是否處于“com.hwldzh.ThirdActivity”的任務(wù)棧中:
Running activities (most recent first):
TaskRecord{853dee #503 A=com.hwldzh.myapplication U=0 StackId=1 sz=3}
Run #4: ActivityRecord{c1a608e u0 com.hwldzh.myapplication/.ThirdActivity t503}
Run #3: ActivityRecord{7289178 u0 com.hwldzh.myapplication/.SecondActivity t503}
Run #2: ActivityRecord{8539f65 u0 com.hwldzh.myapplication/.MainActivity t503}
可以看到ThirdActivity依然運(yùn)行在以包名為名字的任務(wù)棧中富稻。這說(shuō)明了在啟動(dòng)模式為Standard下掷邦,單獨(dú)使用TaskAffinity屬性是無(wú)效的。
3椭赋、TaskAffinity和SingleTask配合
我們?cè)赥hirdActivity的Manifest聲明中加上SingleTask啟動(dòng)模式:
<activity
android:name=".ThirdActivity"
android:launchMode="singleTask"
android:taskAffinity="com.hwldzh.ThirdActivity"/>
然后執(zhí)行adb shell dumpsys activity命令抚岗,得到如下結(jié)果:
Running activities (most recent first):
TaskRecord{5da8e4c #25630 A=com.hwldzh.ThirdActivity U=0 StackId=1 sz=1}
Run #7: ActivityRecord{1111a92 u0 com.hwldzh.myapplication/.ThirdActivity t25630}
TaskRecord{b00bc91 #25629 A=com.hwldzh.myapplication U=0 StackId=1 sz=2}
Run #6: ActivityRecord{93040cf u0 com.hwldzh.myapplication/.SecondActivity t25629}
Run #5: ActivityRecord{464be1f u0 com.hwldzh.myapplication/.MainActivity t25629}
在將ThirdActivity的啟動(dòng)模式改為SingleTask之后,可以看到ThirdActivity啟動(dòng)的時(shí)候創(chuàng)建了一個(gè)新的任務(wù)棧哪怔,并且該任務(wù)棧的名字為T(mén)askAffinity屬性設(shè)置的“com.hwldzh.ThirdActivity”宣蔚。
所以,當(dāng)TaskAffinity和SingleTask啟動(dòng)模式配對(duì)使用時(shí)认境,它是具有該模式的Activity的目前任務(wù)棧的名字胚委,待啟動(dòng)的Activity會(huì)運(yùn)行在名字和TaskAffinity相同的任務(wù)棧中。
二元暴、allowTaskReparenting
allowTaskReparenting屬性的作用是Activity的遷移篷扩。當(dāng)allowTaskReparenting屬性和TaskAffinity配合使用時(shí),Activity可以從一個(gè)任務(wù)棧遷移到另一個(gè)任務(wù)棧茉盏。
遷移的規(guī)則是:從一個(gè)與該Activity TaskAffinity屬性不同的任務(wù)棧中遷移到與它TaskAffinity相同的任務(wù)棧中鉴未。
舉個(gè)例子:當(dāng)一個(gè)應(yīng)用A啟動(dòng)了應(yīng)用B的某個(gè)Activity后,如果這個(gè)Activity的allowTaskReparenting屬性設(shè)置為true鸠姨,那么當(dāng)應(yīng)用B被啟動(dòng)铜秆,此Activity會(huì)直接從應(yīng)用A的任務(wù)棧轉(zhuǎn)移到應(yīng)用B的任務(wù)棧中。
具體點(diǎn)來(lái)說(shuō)讶迁,現(xiàn)在有兩個(gè)應(yīng)用A和B连茧,A啟動(dòng)了B的一個(gè)Activity C,然后按Home鍵回到桌面,然后再單擊B的桌面圖標(biāo)啸驯,這個(gè)時(shí)候不是啟動(dòng)了B的主Activity客扎,而是重新顯示了已經(jīng)被應(yīng)用A啟動(dòng)的Activity C。我們也可以理解為罚斗,C從A的任務(wù)棧轉(zhuǎn)移到了B的任務(wù)棧中徙鱼。
可以這么理解,由于A啟動(dòng)了C针姿,這個(gè)時(shí)候C只能運(yùn)行在A的任務(wù)棧中袱吆,但是C屬于B應(yīng)用,正常情況下距淫,它的TaskAffinity值肯定不可能和A的任務(wù)棧相同绞绒,所以當(dāng)B啟動(dòng)后,B會(huì)創(chuàng)建自己的任務(wù)棧榕暇,這個(gè)時(shí)候系統(tǒng)發(fā)現(xiàn)C原本想要的任務(wù)棧已經(jīng)創(chuàng)建了蓬衡,所以就把C從A的任務(wù)棧中轉(zhuǎn)移過(guò)來(lái)了。
參考書(shū)目
1拐揭、《Android開(kāi)發(fā)藝術(shù)探索》