Android TaskAffinity和allowTaskReparenting屬性

一、TaskAffinity

TaskAffinity翻譯過來就是“任務(wù)相關(guān)性”,它表示了一個Activity所需要的任務(wù)棧的名字。
在平時的開發(fā)中,我們一般很少使用到TaskAffinity這個屬性,也沒有聽說過Activity需要什么任務(wù)棧之類的。其實,在默認情況下,如果不指定TaskAffinity屬性,Activity所需任務(wù)棧的名字就是應(yīng)用的名字。

1、默認的任務(wù)棧

我們在一個應(yīng)用中啟動三個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}

可以看到,啟動的三個Activity都位于“com.hwldzh.application”這個任務(wù)棧中,而這個名字就是我們這個應(yīng)用的包名。

2、TaskAffinity初登場

接下來,我們給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依然運行在以包名為名字的任務(wù)棧中。這說明了在啟動模式為Standard下,單獨使用TaskAffinity屬性是無效的。

3、TaskAffinity和SingleTask配合

我們在ThirdActivity的Manifest聲明中加上SingleTask啟動模式:

<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的啟動模式改為SingleTask之后,可以看到ThirdActivity啟動的時候創(chuàng)建了一個新的任務(wù)棧,并且該任務(wù)棧的名字為TaskAffinity屬性設(shè)置的“com.hwldzh.ThirdActivity”。

所以,當(dāng)TaskAffinity和SingleTask啟動模式配對使用時,它是具有該模式的Activity的目前任務(wù)棧的名字,待啟動的Activity會運行在名字和TaskAffinity相同的任務(wù)棧中。

二、allowTaskReparenting

allowTaskReparenting屬性的作用是Activity的遷移。當(dāng)allowTaskReparenting屬性和TaskAffinity配合使用時,Activity可以從一個任務(wù)棧遷移到另一個任務(wù)棧。

遷移的規(guī)則是:從一個與該Activity TaskAffinity屬性不同的任務(wù)棧中遷移到與它TaskAffinity相同的任務(wù)棧中。

舉個例子:當(dāng)一個應(yīng)用A啟動了應(yīng)用B的某個Activity后,如果這個Activity的allowTaskReparenting屬性設(shè)置為true,那么當(dāng)應(yīng)用B被啟動,此Activity會直接從應(yīng)用A的任務(wù)棧轉(zhuǎn)移到應(yīng)用B的任務(wù)棧中。
具體點來說,現(xiàn)在有兩個應(yīng)用A和B,A啟動了B的一個Activity C,然后按Home鍵回到桌面,然后再單擊B的桌面圖標(biāo),這個時候不是啟動了B的主Activity,而是重新顯示了已經(jīng)被應(yīng)用A啟動的Activity C。我們也可以理解為,C從A的任務(wù)棧轉(zhuǎn)移到了B的任務(wù)棧中。
可以這么理解,由于A啟動了C,這個時候C只能運行在A的任務(wù)棧中,但是C屬于B應(yīng)用,正常情況下,它的TaskAffinity值肯定不可能和A的任務(wù)棧相同,所以當(dāng)B啟動后,B會創(chuàng)建自己的任務(wù)棧,這個時候系統(tǒng)發(fā)現(xiàn)C原本想要的任務(wù)棧已經(jīng)創(chuàng)建了,所以就把C從A的任務(wù)棧中轉(zhuǎn)移過來了。

參考書目

1、《Android開發(fā)藝術(shù)探索》

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容