blow your mind
bym系列意在除開技術(shù)分享,還分享下思路,不止是做一個代碼的搬運工。
背景介紹
最近在閱讀《Android開發(fā)藝術(shù)探索》,書是2015年出的,但是內(nèi)容卻對我來說是新的。在1.2 Activity的啟動模式一章中有這么一段話。
TaskAffinity,可以翻譯為任務相關(guān)性。這個參數(shù)標識了一個Activity所需要的任務棧的名字,默認情況下,所有Activity所需的任務棧的名字為應用的包名。當然,我們可以為每個Activity都單獨指定TaskAffinity屬性,這個屬性值必須不能和包名相同,否則就相當于沒有指定。TaskAffinity屬性主要和singleTask啟動模式或者allowTaskReparenting屬性配對使用,在其他情況下沒有意義。另外,任務棧分為前臺任務棧和后臺任務棧,后臺任務棧中的Activity位于暫停狀態(tài),用戶可以通過切換將后臺任務棧再次調(diào)到前臺。
前臺任務棧和后臺任務棧
首先官方并沒有定義這兩個概念,筆者應該是方便理解自行定義的。我們可以做如下理解
- 前臺任務棧:當前處于前臺并運行、可見并能和用戶交互的APP應用所在的棧。
- 后臺任務棧:當前處于后臺、不可見也不能和用戶交互的APP應用所在的棧。
當TaskAffinity和singleTask啟動模式配對使用的時候,它是具有該模式的Activity的目前任務棧的名字,待啟動的Activity會運行在名字和TaskAffinity相同的任務棧中。
TaskAffinity+singleTask
創(chuàng)建一個默認啟動模式的KtActivity和一個SingleTask加上android:taskAffinity="com.markfrain.singleTask"的SingleTaskActivity。
接口我們先啟動KtActivity,從KtActivity中啟動single
Running activities (most recent first):
TaskRecord{b85f8b6 #2082 A=com.bimfoo.tools.demo U=0 StackId=1981 sz=1}
Run #0: ActivityRecord{fcca610 u0 com.bimfoo.tools.demo/.ui.KtActivity t2082}
mResumedActivity: ActivityRecord{fcca610 u0 com.bimfoo.tools.demo/.ui.KtActivity t2082}
Running activities (most recent first):
TaskRecord{c9689b7 #2081 A=com.markfrain.singleTask U=0 StackId=1980 sz=1}
Run #0: ActivityRecord{a3a31cb u0 com.bimfoo.tools.demo/.ui.SingleTaskActivity t2081}
問題出現(xiàn)了,并沒有像文字描述那樣KtActivity在與SingleTaskActivity在一個任務棧中。
或許文字的意思只是單指SingleTaskActivity會在taskAffinity字段指定的任務棧中?如果是這樣那就沒錯了。
好的接下來看第二段
當TaskAffinity和allowTaskReparenting結(jié)合的時候,這種情況比較復雜,會產(chǎn)生特殊的效果。當一個應用A啟動了應用B的某個Activity后,如果這個Activity的allowTaskReparenting屬性為true的話,那么當應用B被啟動后,此Activity會直接從應用A的任務棧轉(zhuǎn)移到應用B的任務棧中。這還是很抽象,再具體點,比如現(xiàn)在有2個應用A和B, A啟動了B的一個Activity C,然后按Home鍵回到桌面,然后再單擊B的桌面圖標,這個時候并不是啟動了B的主Activity,而是重新顯示了已經(jīng)被應用A啟動的Activity C,或者說,C從A的任務棧轉(zhuǎn)移到了B的任務棧中??梢赃@么理解,由于A啟動了C,這個時候C只能運行在A的任務棧中,但是C屬于B應用,正常情況下,它的TaskAffinity值肯定不可能和A的任務棧相同(因為包名不同)。所以,當B被啟動后,B會創(chuàng)建自己的任務棧,這個時候系統(tǒng)發(fā)現(xiàn)C原本所想要的任務棧已經(jīng)被創(chuàng)建了,所以就把C從A的任務棧中轉(zhuǎn)移過來了。
TaskAffinity和allowTaskReparenting
根據(jù)上面的文字描述, 讓我想起了最近玩的淘寶的芭芭農(nóng)場,??哈哈,我畫個圖來演示下上述過程吧。讀者看到也可以玩玩芭芭農(nóng)場就能明白allowTaskReparenting這個屬性了。如下圖
應用A啟動應用B的某個Activity淘寶芭芭農(nóng)場啟動支付寶芭芭農(nóng)場
home鍵后,點擊應用B的圖標home鍵后,點擊支付寶圖標
allowTaskReparenting如果設置為flase就是不允許將Activity移入其他的任務棧。
參考資料 《Android開發(fā)藝術(shù)探索》