基本概念
一般來(lái)說(shuō)姥闪,Task指的是與用戶交互的Activity的集合,這些Activity集合按照打開(kāi)的順序被放置在同一個(gè)棧中堵腹,這個(gè)棧叫做Back Stack(后退棧)涵防。
Task是可以跨應(yīng)用的,這正是Task存在的一個(gè)重要原因亡电。有的Activity届巩,雖然不在同一個(gè)app中,但為了保持用戶操作的連貫性份乒,把他們放在同一個(gè)任務(wù)中恕汇。例如,在我們的應(yīng)用中的一個(gè)ActivityA中點(diǎn)擊發(fā)送郵件或辖,會(huì)啟動(dòng)郵件程序的一個(gè)ActivityB來(lái)發(fā)送郵件瘾英,這兩個(gè)Activity是存在于不同app中的,但是被系統(tǒng)放在一個(gè)任務(wù)中颂暇,這樣當(dāng)發(fā)送完郵件后缺谴,用戶按back鍵返回,可以返回到原來(lái)的ActivityA中耳鸯,這樣就確保了用戶體驗(yàn)湿蛔。
每個(gè)Task都存在一個(gè)Back Stack,而系統(tǒng)中可以存在多個(gè)Task片拍,但是每次只有一個(gè)Task獲得前臺(tái)焦點(diǎn)煌集,一般而言,系統(tǒng)允許用戶在多個(gè)Task中切換捌省,而被至于后臺(tái)的Task中的Activity苫纤,將被置于Stopped狀態(tài)。實(shí)際上纲缓,同一個(gè)Task中的Activity卷拘,只要不存在于棧頂并且獲得前臺(tái)焦點(diǎn)的Activity,那么它就是一個(gè)Stopped的狀態(tài)祝高。下圖為官方文檔中關(guān)于Task前后臺(tái)的示例圖:
Activity四種啟動(dòng)模式
standard
標(biāo)準(zhǔn)模式栗弟,也是Activity默認(rèn)啟動(dòng)模式。如果某個(gè)Activity使用該LaunchMode工闺, 當(dāng)這個(gè)Activity啟動(dòng)時(shí)乍赫,系統(tǒng)會(huì)創(chuàng)建一個(gè)該Activity新的實(shí)例瓣蛀,并且傳遞 一個(gè)intent給它。該 Activity可以被實(shí)例化多次雷厂,各個(gè)實(shí)例可以屬于不同的Task惋增,一個(gè)Task 中也可以存在多個(gè)實(shí)例。
singleTop
singleTop其實(shí)和standard幾乎一樣改鲫,使用singleTop的Activity也可以創(chuàng)建很多個(gè)實(shí)例诈皿。唯一不同的就是,如果調(diào)用的目標(biāo)Activity已經(jīng)位于調(diào)用者的Task的棧頂像棘,則不創(chuàng)建新實(shí)例稽亏,而是使用當(dāng)前的這個(gè)Activity實(shí)例,并調(diào)用這個(gè)實(shí)例的onNewIntent方法缕题。
singleTask
singleTask這個(gè)模式和前面提到的standard和singleTop截然不同截歉。使用singleTask啟動(dòng)模式的Activity在系統(tǒng)中只會(huì)存在一個(gè)實(shí)例。如果這個(gè)實(shí)例已經(jīng)存在烟零,intent就會(huì)通過(guò)onNewIntent傳遞到這個(gè)Activity怎披。否則新的Activity實(shí)例被創(chuàng)建。
同一應(yīng)用
如果系統(tǒng)中不存在singleTask Activity的實(shí)例瓶摆,那么就需要?jiǎng)?chuàng)建這個(gè)Activity的實(shí)例,并且將這個(gè)實(shí)例放入和調(diào)用者相同的Task中并位于棧頂性宏。
如果singleTask Activity實(shí)例已然存在群井,那么在Activity回退棧中,所有位于該Activity上面的Activity實(shí)例都將被銷毀掉(銷毀過(guò)程會(huì)調(diào)用Activity生命周期回調(diào))毫胜,這樣使得singleTask Activity實(shí)例位于棧頂书斜。與此同時(shí),Intent會(huì)通過(guò)onNewIntent傳遞到這個(gè)SingleTask Activity實(shí)例酵使。
跨應(yīng)用
在跨應(yīng)用Intent傳遞時(shí)荐吉,如果系統(tǒng)中不存在singleTask Activity的實(shí)例,那么講創(chuàng)建一個(gè)新的Task口渔,然后創(chuàng)建SingleTask Activity的實(shí)例样屠,將其放入新的Task中。
如果singleTask Activity所在的應(yīng)用進(jìn)程存在缺脉,但是singleTask Activity實(shí)例不存在痪欲,那么從別的應(yīng)用啟動(dòng)這個(gè)Activity,新的Activity實(shí)例會(huì)被創(chuàng)建攻礼,并放入到所屬進(jìn)程所在的Task中业踢,并位于棧頂位置。
更復(fù)雜的一種情況礁扮,如果singleTask Activity實(shí)例存在知举,從其他程序被啟動(dòng)瞬沦,那么這個(gè)Activity所在的Task會(huì)被移到頂部,并且在這個(gè)Task中雇锡,位于singleTask Activity實(shí)例之上的所有Activity將會(huì)被正常銷毀掉逛钻。如果我們按返回鍵,那么我們首先會(huì)回退到這個(gè)Task中的其他Activity遮糖,直到當(dāng)前Task的Activity回退棧為空時(shí)绣的,才會(huì)返回到調(diào)用者的Task。
singleInstance
這個(gè)模式和singleTask差不多欲账,因?yàn)樗麄冊(cè)谙到y(tǒng)中都只有一份實(shí)例屡江。唯一不同的就是存放singleInstance Activity實(shí)例的Task只能存放一個(gè)該模式的Activity實(shí)例。如果從singleInstance Activity實(shí)例啟動(dòng)另一個(gè)Activity赛不,那么這個(gè)Activity實(shí)例會(huì)放入其他的Task中惩嘉。同理,如果singleInstance Activity被別的Activity啟動(dòng)踢故,它也會(huì)放入不同于調(diào)用者的Task中文黎。
<p>
參考
深入講解Android中Activity launchMode
Activity啟動(dòng)模式 及 Intent Flags 與 棧 的關(guān)聯(lián)分析