blow your mind
bym系列意在除開技術(shù)分享籍凝,還分享下思路周瞎,不止是做一個(gè)代碼的搬運(yùn)工饵蒂。
背景介紹
最近在閱讀《Android開發(fā)藝術(shù)探索》,書是2015年出的苹享,但是內(nèi)容卻對(duì)我來說是新的。在1.2 Activity的啟動(dòng)模式
一章中有這么一段話得问。
TaskAffinity,可以翻譯為任務(wù)相關(guān)性宫纬。這個(gè)參數(shù)標(biāo)識(shí)了一個(gè)Activity所需要的任務(wù)棧的名字,默認(rèn)情況下漓骚,所有Activity所需的任務(wù)棧的名字為應(yīng)用的包名蝌衔。當(dāng)然蝌蹂,我們可以為每個(gè)Activity都單獨(dú)指定TaskAffinity屬性,這個(gè)屬性值必須不能和包名相同孤个,否則就相當(dāng)于沒有指定。TaskAffinity屬性主要和singleTask啟動(dòng)模式或者allowTaskReparenting屬性配對(duì)使用齐鲤,在其他情況下沒有意義。另外给郊,任務(wù)棧分為前臺(tái)任務(wù)棧和后臺(tái)任務(wù)棧牡肉,后臺(tái)任務(wù)棧中的Activity位于暫停狀態(tài)统锤,用戶可以通過切換將后臺(tái)任務(wù)棧再次調(diào)到前臺(tái)。
前臺(tái)任務(wù)棧和后臺(tái)任務(wù)棧
首先官方并沒有定義這兩個(gè)概念炭庙,筆者應(yīng)該是方便理解自行定義的。我們可以做如下理解
- 前臺(tái)任務(wù)棧:當(dāng)前處于前臺(tái)并運(yùn)行煤搜、可見并能和用戶交互的APP應(yīng)用所在的棧唧席。
- 后臺(tái)任務(wù)棧:當(dāng)前處于后臺(tái)嘲驾、不可見也不能和用戶交互的APP應(yīng)用所在的棧。
當(dāng)TaskAffinity和singleTask啟動(dòng)模式配對(duì)使用的時(shí)候辽故,它是具有該模式的Activity的目前任務(wù)棧的名字,待啟動(dòng)的Activity會(huì)運(yùn)行在名字和TaskAffinity相同的任務(wù)棧中誊垢。
TaskAffinity+singleTask
創(chuàng)建一個(gè)默認(rèn)啟動(dòng)模式的KtActivity和一個(gè)SingleTask加上android:taskAffinity="com.markfrain.singleTask"
的SingleTaskActivity。
接口我們先啟動(dòng)KtActivity症见,從KtActivity中啟動(dòng)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在一個(gè)任務(wù)棧中谋作。
或許文字的意思只是單指SingleTaskActivity會(huì)在taskAffinity字段指定的任務(wù)棧中?如果是這樣那就沒錯(cuò)了遵蚜。
好的接下來看第二段
當(dāng)TaskAffinity和allowTaskReparenting結(jié)合的時(shí)候,這種情況比較復(fù)雜吭净,會(huì)產(chǎn)生特殊的效果睡汹。當(dāng)一個(gè)應(yīng)用A啟動(dòng)了應(yīng)用B的某個(gè)Activity后寂殉,如果這個(gè)Activity的allowTaskReparenting屬性為true的話溶浴,那么當(dāng)應(yīng)用B被啟動(dòng)后屁柏,此Activity會(huì)直接從應(yīng)用A的任務(wù)棧轉(zhuǎn)移到應(yīng)用B的任務(wù)棧中焕檬。這還是很抽象姆坚,再具體點(diǎn)实愚,比如現(xiàn)在有2個(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ù)棧相同(因?yàn)榘煌K孕托停?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)移過來了绷落。
TaskAffinity和allowTaskReparenting
根據(jù)上面的文字描述, 讓我想起了最近玩的淘寶的芭芭農(nóng)場(chǎng)
砌烁,??哈哈,我畫個(gè)圖來演示下上述過程吧函喉。讀者看到也可以玩玩芭芭農(nóng)場(chǎng)就能明白allowTaskReparenting這個(gè)屬性了避归。如下圖
應(yīng)用A啟動(dòng)應(yīng)用B的某個(gè)Activity淘寶芭芭農(nóng)場(chǎng)啟動(dòng)支付寶芭芭農(nóng)場(chǎng)
home鍵后梳毙,點(diǎn)擊應(yīng)用B的圖標(biāo)home鍵后,點(diǎn)擊支付寶圖標(biāo)
allowTaskReparenting如果設(shè)置為flase就是不允許將Activity移入其他的任務(wù)棧账锹。
參考資料 《Android開發(fā)藝術(shù)探索》