任務(wù)和返回棧

原始文檔

docs/guide/components/tasks-and-back-stack.html

任務(wù)

  1. 任務(wù)(Task)是用戶執(zhí)行特定作業(yè)時(shí)的一系列交互活動(dòng)(Activity)务荆。這些活動(dòng)以打開的順序被存放在堆棧(返回棧)中贱勃。
  2. 當(dāng)Activity啟動(dòng)另外一個(gè)Activity,那么新的Activity被放置到棧的頂部并獲取焦點(diǎn)砌左。前一個(gè)Activity依然保留在棧中泽裳,但是出于停止?fàn)顟B(tài)例证。系統(tǒng)會(huì)保存處于停止?fàn)顟B(tài)的Activity的用戶界面。用戶摁返回鍵畦幢,當(dāng)前的Activity彈出銷毀入热,前一個(gè)Activity恢復(fù)執(zhí)行。整個(gè)啟動(dòng)-返回退出Activity的操作如下圖所示解总。


  3. 當(dāng)所有的Activity從棧中移除時(shí)贮匕,任務(wù)被銷毀。
  4. 返回棧中的所有Activity是不能重新被排序的花枫,這樣的話刻盐,如果允許一個(gè)Activity可以被多個(gè)其他Activity啟動(dòng)的話,那么每次會(huì)實(shí)例化一個(gè)Activity,并保存在棧中劳翰《匦浚可以通過啟動(dòng)方式來管理是否每次 都實(shí)例化一個(gè)全新的Activity。
  5. 當(dāng)用戶通過主頁按鈕離開當(dāng)前任務(wù)佳簸,當(dāng)前Activity停止乙墙,當(dāng)前任務(wù)進(jìn)入到后臺。系統(tǒng)會(huì)保持任務(wù)中的每個(gè)Activity的狀態(tài)生均。當(dāng)用戶通過點(diǎn)擊啟動(dòng)圖標(biāo)听想,任務(wù)恢復(fù)進(jìn)入前臺,任務(wù)頂端的Activity恢復(fù)狀態(tài)马胧。

Activity狀態(tài)保存

盡管系統(tǒng)會(huì)自動(dòng)保存后臺的Activity的狀態(tài)哗魂,但是如果在內(nèi)存緊張的情況下,系統(tǒng)會(huì)銷毀后臺Activity漓雅。這樣的話录别,一些Activity的重要的信息就會(huì)丟失朽色,在下次改Activity進(jìn)入前臺的時(shí)候,該意外銷毀的Activity會(huì)被重新創(chuàng)建组题,無法恢復(fù)葫男。為避免這種情況的發(fā)生,應(yīng)該主動(dòng)地調(diào)用onSaveInstanceState()來保存狀態(tài)崔列。

任務(wù)管理

正常的task是一個(gè)“先入后出”的堆棧梢褐,每次都實(shí)例一個(gè)Activity并且壓入堆棧。如果想打破這種常規(guī)赵讯,可以在AndroidManifest.xml的Activity申明啟動(dòng)模式盈咳、啟動(dòng)屬性等或者在startActivity()時(shí)指定標(biāo)志位。

清單文件中指定可使用屬性:

  1. taskAffinity (任務(wù)親戚關(guān)系)
  2. launchMode
  3. allowTaskReparenting
  4. clearTaskOnLaunch
  5. alwaysRetainTaskState
  6. finishOnTaskLaunch

Intent標(biāo)志:

  1. FLAG_Activity_NEW_TASK
  2. FLAG_Activity_CLEAR_TOP
  3. FLAG_Activity_SINGLE_TOP

在Intent和清單文件中啟動(dòng)方式發(fā)生沖突時(shí)边翼,以Intent中的啟動(dòng)方式為準(zhǔn)鱼响。

launchMode 啟動(dòng)模式

  1. "standard"
    默認(rèn)啟動(dòng)方式,每次在任務(wù)種實(shí)例化一個(gè)Activity组底。一個(gè)Activity被實(shí)例化多次丈积,每個(gè)實(shí)例可能隸屬于不同的任務(wù),一個(gè)任務(wù)可能擁有多個(gè)該Activity的實(shí)例债鸡。
  2. "singleTop"
    如果返回棧中存在Activity的實(shí)例江滨,并且該實(shí)例在任務(wù)的頂部,那么通過調(diào)用onNewIntent()進(jìn)入該Activity厌均,并不會(huì)重新實(shí)例化一個(gè)Activity唬滑。確保任務(wù)頂部的兩個(gè)Activity不重復(fù).
    例如任務(wù)A-B-C-D,現(xiàn)在一個(gè)新的Intent啟動(dòng)D,如果D是默認(rèn)啟動(dòng)方式的話,會(huì)實(shí)例化一個(gè)先的Activity D棺弊,任務(wù)變成A-B-C-D-D;如果是singleTop的話间雀,只會(huì)調(diào)用D的onNewIntent()方法,任務(wù)依然是A-B-C-D镊屎。但是如果啟動(dòng)B的話惹挟,任務(wù)變成A-B-C-D-B,即使啟動(dòng)方式是singleTop。
  3. "singleTask"
    所有的任務(wù)(返回棧)中僅能存在一個(gè)實(shí)例缝驳。如果所有的任務(wù)中不存在該Activity的實(shí)例连锯,那么實(shí)例化一個(gè)該Activity。如果存在的話用狱,那么進(jìn)入該Activity的onNewIntent()的方法运怖。
    對于這種啟動(dòng)方式的Activity,對于返回的處理是比較特殊的。如果從一個(gè)新的任務(wù)中啟動(dòng)一個(gè)其他任務(wù)已存在的Activity夏伊,那么相當(dāng)于比之前任務(wù)的返回棧堆疊到到當(dāng)前堆棧上摇展。如下圖所示.
![](http://upload-images.jianshu.io/upload_images/2682632-c754c954576b2822.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

在上圖中Y是singleTask啟動(dòng)方式,Activity2啟動(dòng)Y后溺忧,摁返回咏连,不會(huì)立即返回到Activity2盯孙,而是按照Y所在的堆棧進(jìn)行返回。如果后臺任務(wù)順序?yàn)閄-Y-W,那么啟動(dòng)Y的時(shí)候祟滴,會(huì)先調(diào)用W.onDestory(),銷毀W,彈出Y振惰。

  1. "singleInstance"
    這種方式是所有任務(wù)中只有一個(gè)Activity實(shí)例,這點(diǎn)跟singleTask是一樣的垄懂。所不同的是骑晶,該Activity獨(dú)占一個(gè)任務(wù),該任務(wù)不含其他的Activity草慧。

使用Intent標(biāo)志

可以在調(diào)用startActivity()時(shí)指定標(biāo)志位來指定Activity的啟動(dòng)方式桶蛔。

  1. FLAG_NEW_TASK:
    這種調(diào)用方式與在AndroidManifest.xml文檔中申明Activity的launchMode為singleTask產(chǎn)生的效果一樣.
  2. FLAG_Activity_SINGLE_TOP:
    這種調(diào)用方式與在AndroidManifest.xml文檔中申明Activity的launchMode為singleTop產(chǎn)生的效果一樣.
  3. FLAG_Activity_CLEAR_TOP:
    如果調(diào)用的Activity在當(dāng)前的任務(wù)中存在的話,那么:

a. 如果啟動(dòng)清單文件中啟動(dòng)方式為standard的話漫谷,那么找到該Activity在堆棧中的位置仔雷,將自身和其堆棧上層的所有Activity都o(jì)nDestory()掉,重新在頂層實(shí)例化一個(gè)新的Activity.
b. 如果啟動(dòng)清單文件中啟動(dòng)方式不為standard的話抖剿,那么找到該Activity在堆棧中的位置,將其堆棧上層的所有Activity都o(jì)nDestory()掉识窿,并且通過onNewIntent()恢復(fù)該Activity.

FLAG_Activity_CLEARTOP和FLAG_NEW_TASK經(jīng)常被組合使用斩郎。當(dāng)組合使用時(shí),會(huì)在所有任務(wù)中定位到一個(gè)已經(jīng)存在的Activity,清除包含該Activity的任務(wù)中處于上層的Activity喻频,并在頂層響應(yīng)該Intent缩宜。

處理關(guān)聯(lián)(affinities)

關(guān)聯(lián)(affinity)指一個(gè)Activity所在的任務(wù)。默認(rèn)甥温,同一個(gè)應(yīng)用中的所有Activity都隸屬于同一個(gè)任務(wù)锻煌。然而,可以在AndroidManifest.xml中通過taskAffinity指定一個(gè)關(guān)聯(lián)姻蚓,不同application可以共享一個(gè)關(guān)聯(lián)(任務(wù))宋梧,而同一個(gè)application的不同Activity可以有不同關(guān)聯(lián)。taskAffinity要跟包名不同狰挡,否則就跟默認(rèn)的一樣了.

兩種應(yīng)用場景

  1. 以FLAG_Activity_NEW_TASK啟動(dòng)Activity

在以FLAG_ACTIVIY_NEW_TASK啟動(dòng)Activity時(shí)捂龄,如果Activity已經(jīng)在其他的任務(wù)中已經(jīng)啟動(dòng)過了,那么啟動(dòng)改Activity啟動(dòng)時(shí)會(huì)將其他任務(wù)中的Activity帶入到當(dāng)前返回棧中加叁,那么返回的時(shí)候就會(huì)出現(xiàn)其他任務(wù)的Activity倦沧。這時(shí),可以在Activity的AndroidManifest它匕。xml申明時(shí)指定其關(guān)聯(lián)展融,這樣的話,只會(huì)待會(huì)與其關(guān)聯(lián)值一樣的Activity才會(huì)在一個(gè)任務(wù)中豫柬,那么返回退出的時(shí)候就只會(huì)出現(xiàn)關(guān)聯(lián)任務(wù)的Activity.

  1. 當(dāng)Activity的allowTaskReparenting屬性為true時(shí)

設(shè)置這個(gè)屬性值告希,在當(dāng)前application A的Activity a中啟動(dòng)其他關(guān)聯(lián)的Activity 1后扑浸,當(dāng)A切換到后臺,再重新切回到前臺后暂雹,呈現(xiàn)的是Activity a首装。而Activity 1被重新規(guī)劃到其關(guān)聯(lián)的任務(wù)中。如果有application B的taskAffinity跟Activity1的值一樣的話杭跪,那么可以通過點(diǎn)擊application B后看到Activity 1的界面了仙逻。

返回棧清除

如果用戶離開任務(wù)很長一段時(shí)間,那么系統(tǒng)會(huì)只會(huì)保留任務(wù)中的根Activity而清除其他Activity涧尿。

  1. alwaysRetainTaskState
    為任務(wù)的根Activity設(shè)置為ture的話,那么任務(wù)會(huì)一直保持它的堆棧系奉,即使在很長時(shí)間后。
  2. clearTaskOnLaunch
    這個(gè)是alwaysRetainTaskState屬性的方面姑廉,設(shè)置根Activity的該屬性為true的話缺亮,每次離開任務(wù),再次進(jìn)入任務(wù)都會(huì)從根Activity恢復(fù)桥言。其他的被remove()掉萌踱。
  3. finishOnTaskLaunch
    這個(gè)屬性可以賦值給一個(gè)非根Activity(根Activity是無效的)。如果設(shè)置為true,那么每次重新進(jìn)入任務(wù)都會(huì)remove掉該Activity,摁返回鍵号阿,返回不會(huì)再返回這個(gè)Activity并鸵。

啟動(dòng)任務(wù)

使用MAIN屬性值的action和LAUNCHER的CATEGORY的話,點(diǎn)擊LAUCHER的圖標(biāo)可以啟動(dòng)根Activity進(jìn)而啟動(dòng)任務(wù)。但是LAUNCHER點(diǎn)擊圖標(biāo)還有一個(gè)效果扔涧,即返回任務(wù)园担。試想一下,要是沒有這個(gè)效果枯夜,那每次任務(wù)切換到后臺重新進(jìn)入后弯汰,任務(wù)都沒法恢復(fù)了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末湖雹,一起剝皮案震驚了整個(gè)濱河市咏闪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌摔吏,老刑警劉巖汤踏,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異舔腾,居然都是意外死亡溪胶,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進(jìn)店門稳诚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來哗脖,“玉大人,你說我怎么就攤上這事〔疟埽” “怎么了橱夭?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長桑逝。 經(jīng)常有香客問我棘劣,道長,這世上最難降的妖魔是什么楞遏? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任茬暇,我火速辦了婚禮,結(jié)果婚禮上寡喝,老公的妹妹穿的比我還像新娘糙俗。我一直安慰自己,他們只是感情好预鬓,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布巧骚。 她就那樣靜靜地躺著,像睡著了一般格二。 火紅的嫁衣襯著肌膚如雪劈彪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天顶猜,我揣著相機(jī)與錄音沧奴,去河邊找鬼。 笑死驶兜,一個(gè)胖子當(dāng)著我的面吹牛扼仲,可吹牛的內(nèi)容都是我干的远寸。 我是一名探鬼主播抄淑,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼驰后!你這毒婦竟也來了肆资?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤灶芝,失蹤者是張志新(化名)和其女友劉穎郑原,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體夜涕,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡犯犁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了女器。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酸役。...
    茶點(diǎn)故事閱讀 40,427評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出涣澡,到底是詐尸還是另有隱情贱呐,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布入桂,位于F島的核電站奄薇,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏抗愁。R本人自食惡果不足惜馁蒂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望驹愚。 院中可真熱鬧远搪,春花似錦、人聲如沸逢捺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽劫瞳。三九已至倘潜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間志于,已是汗流浹背涮因。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留伺绽,地道東北人养泡。 一個(gè)月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像奈应,于是被迫代替她去往敵國和親澜掩。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評論 2 359

推薦閱讀更多精彩內(nèi)容