任務(wù)和返回棧
使用android:launchMode="standard|singleInstance|single Task|singleTop"來控制Acivity任務(wù)棧。
任務(wù)棧是一種后進先出的結(jié)構(gòu)盲赊。位于棧頂?shù)腁ctivity處于焦點狀態(tài),當按下back按鈕的時候,棧內(nèi)的Activity會一個一個的出棧,并且調(diào)用其onDestory()方法剥啤。如果棧內(nèi)沒有Activity,那么系統(tǒng)就會回收這個棧,每個APP默認只有一個棧,以APP的包名來命名.
任務(wù)是指在執(zhí)行特定作業(yè)時與用戶交互的一系列 Activity檩小。 這些 Activity 按照各自的打開順序排列在堆棧(即返回棧)中验毡。
例如:你在主屏幕中打開一個應(yīng)用陵且,其實就是開啟了一個activity卦碾,然后又由這個activity開啟了一系列其他的activity图云,這些activity可能屬于同一個應(yīng)用也可能屬于不同的應(yīng)用物喷。但只要是在這一系列的操作中打開的activity卤材,他們就都處于同一個Task(任務(wù))當中。
設(shè)備的主屏幕是大多數(shù)任務(wù)的起點.當用戶觸摸應(yīng)用啟動器中的圖標時峦失,該應(yīng)用的任務(wù)將出現(xiàn)在前臺扇丛。 如果應(yīng)用不存在任務(wù)(應(yīng)用最近未曾使用),則會創(chuàng)建一個新任務(wù)尉辑,并且該應(yīng)用的“主”Activity 將作為堆棧中的根 Activity 打開帆精。
前臺activity:當activity啟動另一個activity時,該新 Activity 會被推送到堆棧頂部,成為焦點所在(前臺activity)卓练。當按下back鍵時隘蝎,系統(tǒng)會將棧頂?shù)腶ctivity銷毀,恢復(fù)前一個activity襟企。
任務(wù)是一個有機整體嘱么,當用戶開始新任務(wù)或通過“主頁”按鈕轉(zhuǎn)到主屏幕時,可以移動到“后臺”顽悼,變成后臺任務(wù)曼振。后臺任務(wù)中的activity全部停止,但其返回棧中activity的順序不變蔚龙。(返回棧中的activity順序永遠不變)冰评。也就是說,當另一個任務(wù)發(fā)生時木羹,該任務(wù)僅僅失去焦點而已集索。
Activity 和任務(wù)的默認行為總結(jié)如下:
- 當 Activity A 啟動 Activity B 時,Activity A 將會停止汇跨,但系統(tǒng)會保留其狀態(tài)(例如务荆,滾動位置和已輸入表單中的文本)。如果用戶在處于 Activity B 時按“返回”按鈕穷遂,則 Activity A 將恢復(fù)其狀態(tài)函匕,繼續(xù)執(zhí)行。
- 用戶通過按“主頁”按鈕離開任務(wù)時蚪黑,當前 Activity 將停止且其任務(wù)會進入后臺盅惜。 系統(tǒng)將保留任務(wù)中每個 Activity 的狀態(tài)。如果用戶稍后通過選擇開始任務(wù)的啟動器圖標來恢復(fù)任務(wù)忌穿,則任務(wù)將出現(xiàn)在前臺并恢復(fù)執(zhí)行堆棧頂部的 Activity抒寂。
- 如果用戶按“返回”按鈕,則當前 Activity 會從堆棧彈出并被銷毀掠剑。 堆棧中的前一個 Activity 恢復(fù)執(zhí)行屈芜。銷毀 Activity 時,系統(tǒng)不會保留該 Activity 的狀態(tài)朴译。
- 即使來自其他任務(wù)井佑,Activity 也可以多次實例化。
四種LaunchMode:
- standard:默認眠寿。系統(tǒng)在啟動 Activity 的任務(wù)中創(chuàng)建 Activity 的新實例并向其傳送 Intent躬翁。Activity 可以多次實例化,而每個實例均可屬于不同的任務(wù)盯拱,并且一個任務(wù)可以擁有多個實例盒发。
- singleTop:如果當前任務(wù)的頂部已存在 Activity 的一個實例例嘱,則系統(tǒng)會通過調(diào)用該實例的 onNewIntent() 方法向其傳送 Intent,而不是創(chuàng)建 Activity 的新實例宁舰。Activity 可以多次實例化蝶防,而每個實例均可屬于不同的任務(wù),并且一個任務(wù)可以擁有多個實例(但前提是位于返回棧頂部的 Activity 并不是 Activity 的現(xiàn)有實例)明吩。**例如间学,假設(shè)任務(wù)的返回棧包含根 Activity A 以及 Activity B、C 和位于頂部的 D(堆棧是 A-B-C-D印荔;D 位于頂部)低葫。收到針對 D 類 Activity 的 Intent。如果 D 具有默認的 "standard" 啟動模式仍律,則會啟動該類的新實例嘿悬,且堆棧會變成 A-B-C-D-D。但是水泉,如果 D 的啟動模式是 "singleTop"善涨,則 D 的現(xiàn)有實例會通過 onNewIntent()接收 Intent,因為它位于堆棧的頂部草则;而堆棧仍為 A-B-C-D钢拧。但是,如果收到針對 B 類 Activity 的 Intent炕横,則會向堆棧添加 B 的新實例源内,即便其啟動模式為 "singleTop"也是如此。
- singleTask:系統(tǒng)創(chuàng)建新任務(wù)并實例化位于新任務(wù)底部的 Activity份殿。但是膜钓,如果該 Activity 的一個實例已存在于一個單獨的任務(wù)中,則系統(tǒng)會通過調(diào)用現(xiàn)有實例的onNewIntent()方法向其傳送 Intent卿嘲,而不是創(chuàng)建新實例颂斜。一次只能存在 Activity 的一個實例。
- singleInstance:與 "singleTask" 相同拾枣,只是系統(tǒng)不會將任何其他 Activity 啟動到包含啟動模式為singleInstance的實例的任務(wù)中沃疮。該 Activity 始終是其任務(wù)唯一僅有的成員;由此 Activity 啟動的任何 Activity 均在單獨的任務(wù)中打開放前。
示例
我們再來看另一示例忿磅,Android 瀏覽器應(yīng)用聲明網(wǎng)絡(luò)瀏覽器 Activity 應(yīng)始終在其自己的任務(wù)中打開(通過在 <activity>元素中指定 singleTask啟動模式)糯彬。這意味著凭语,如果您的應(yīng)用發(fā)出打開 Android 瀏覽器的 Intent,則其 Activity 與您的應(yīng)用位于不同的任務(wù)中撩扒。相反似扔,系統(tǒng)會為瀏覽器啟動新任務(wù)吨些,或者如果瀏覽器已有任務(wù)正在后臺運行,則會將該任務(wù)上移一層以處理新 Intent炒辉。
無論 Activity 是在新任務(wù)中啟動豪墅,還是在與啟動 Activity 相同的任務(wù)中啟動,用戶按“返回”按鈕始終會轉(zhuǎn)到前一個 Activity(始終記住這個邏輯黔寇,系統(tǒng)嚴格按照這個邏輯來執(zhí)行)偶器。 但是,如果啟動指定 singleTask 啟動模式的 Activity缝裤,則當某后臺任務(wù)中存在該 Activity 的實例時屏轰,整個任務(wù)都會轉(zhuǎn)移到前臺。此時憋飞,返回棧包括上移到堆棧頂部的任務(wù)中的所有 Activity霎苗。