任務(wù)和返回棧
應(yīng)用通常包含多個(gè)Activity是鬼。每個(gè) Activity 均應(yīng)圍繞用戶可以執(zhí)行的特定操作設(shè)計(jì),并且能夠啟動(dòng)其他 Activity紫新。 例如均蜜,電子郵件應(yīng)用可能有一個(gè) Activity 顯示新郵件的列表。用戶選擇某郵件時(shí)芒率,會(huì)打開一個(gè)新 Activity 以查看該郵件囤耳。
一個(gè) Activity 甚至可以啟動(dòng)設(shè)備上其他應(yīng)用中存在的 Activity。例如,如果應(yīng)用想要發(fā)送電子郵件充择,則可將 Intent 定義為執(zhí)行“發(fā)送”操作并加入一些數(shù)據(jù)德玫,如電子郵件地址和電子郵件。 然后椎麦,系統(tǒng)將打開其他應(yīng)用中聲明自己處理此類 Intent 的 Activity宰僧。在這種情況下,Intent 是要發(fā)送電子郵件观挎,因此將啟動(dòng)電子郵件應(yīng)用的“撰寫”Activity(如果多個(gè) Activity 支持相同 Intent琴儿,則系統(tǒng)會(huì)讓用戶選擇要使用的 Activity)。發(fā)送電子郵件時(shí)嘁捷,Activity 將恢復(fù)造成,看起來好像電子郵件 Activity 是您的應(yīng)用的一部分。 即使這兩個(gè) Activity 可能來自不同的應(yīng)用雄嚣,但是 Android 仍會(huì)將 Activity 保留在相同的任務(wù)中谜疤,以維護(hù)這種無縫的用戶體驗(yàn)。
任務(wù)是指在執(zhí)行特定作業(yè)時(shí)與用戶交互的一系列 Activity现诀。 這些 Activity 按照各自的打開順序排列在堆棧(即返回棧)中。
設(shè)備主屏幕是大多數(shù)任務(wù)的起點(diǎn)履肃。當(dāng)用戶觸摸應(yīng)用啟動(dòng)器中的圖標(biāo)(或主屏幕上的快捷方式)時(shí)仔沿,該應(yīng)用的任務(wù)將出現(xiàn)在前臺。 如果應(yīng)用不存在任務(wù)(應(yīng)用最近未曾使用)尺棋,則會(huì)創(chuàng)建一個(gè)新任務(wù)封锉,并且該應(yīng)用的“主”Activity 將作為堆棧中的根 Activity 打開。
當(dāng)前 Activity 啟動(dòng)另一個(gè) Activity 時(shí)膘螟,該新 Activity 會(huì)被推送到堆棧頂部成福,成為焦點(diǎn)所在。 前一個(gè) Activity 仍保留在堆棧中荆残,但是處于停止?fàn)顟B(tài)奴艾。Activity 停止時(shí),系統(tǒng)會(huì)保持其用戶界面的當(dāng)前狀態(tài)内斯。 用戶按“返回”按鈕時(shí)蕴潦,當(dāng)前 Activity 會(huì)從堆棧頂部彈出(Activity 被銷毀),而前一個(gè) Activity 恢復(fù)執(zhí)行(恢復(fù)其 UI 的前一狀態(tài))俘闯。 堆棧中的 Activity 永遠(yuǎn)不會(huì)重新排列潭苞,僅推入和彈出堆棧:由當(dāng)前 Activity 啟動(dòng)時(shí)推入堆棧;用戶使用“返回”按鈕退出時(shí)彈出堆棧真朗。 因此此疹,返回棧以“后進(jìn)先出”對象結(jié)構(gòu)運(yùn)行。 圖 1 通過時(shí)間線顯示 Activity 之間的進(jìn)度以及每個(gè)時(shí)間點(diǎn)的當(dāng)前返回棧,直觀呈現(xiàn)了這種行為蝗碎。
用戶按“返回”按鈕時(shí),當(dāng)前 Activity 隨即被銷毀衍菱,而前一個(gè) Activity 恢復(fù)執(zhí)行赶么。
如果用戶繼續(xù)按“返回”,堆棧中的相應(yīng) Activity 就會(huì)彈出脊串,以顯示前一個(gè) Activity辫呻,直到用戶返回主屏幕為止(或者,返回任務(wù)開始時(shí)正在運(yùn)行的任意 Activity)琼锋。 當(dāng)所有 Activity 均從堆棧中移除后放闺,任務(wù)即不復(fù)存在。
任務(wù)是一個(gè)有機(jī)整體谜叹,當(dāng)用戶開始新任務(wù)或通過“主頁”按鈕轉(zhuǎn)到主屏幕時(shí)匾寝,可以移動(dòng)到“后臺”。 盡管在后臺時(shí)荷腊,該任務(wù)中的所有 Activity 全部停止艳悔,但是任務(wù)的返回棧仍舊不變,也就是說女仰,當(dāng)另一個(gè)任務(wù)發(fā)生時(shí)猜年,該任務(wù)僅僅失去焦點(diǎn)而已,如圖 2 中所示疾忍。然后乔外,任務(wù)可以返回到“前臺”,用戶就能夠回到離開時(shí)的狀態(tài)一罩。 例如杨幼,假設(shè)當(dāng)前任務(wù)(任務(wù) A)的堆棧中有三個(gè) Activity,即當(dāng)前 Activity 下方還有兩個(gè) Activity聂渊。 用戶先按“主頁”按鈕推汽,然后從應(yīng)用啟動(dòng)器啟動(dòng)新應(yīng)用。 顯示主屏幕時(shí)歧沪,任務(wù) A 進(jìn)入后臺歹撒。新應(yīng)用啟動(dòng)時(shí),系統(tǒng)會(huì)使用自己的 Activity 堆棧為該應(yīng)用啟動(dòng)一個(gè)任務(wù)(任務(wù) B)诊胞。與該應(yīng)用交互之后暖夭,用戶再次返回主屏幕并選擇最初啟動(dòng)任務(wù) A 的應(yīng)用∏妈荆現(xiàn)在,任務(wù) A 出現(xiàn)在前臺迈着,其堆棧中的所有三個(gè) Activity 保持不變竭望,而位于堆棧頂部的 Activity 則會(huì)恢復(fù)執(zhí)行。 此時(shí)裕菠,用戶還可以通過轉(zhuǎn)到主屏幕并選擇啟動(dòng)該任務(wù)的應(yīng)用圖標(biāo)(或者咬清,通過從概覽屏幕選擇該應(yīng)用的任務(wù))切換回任務(wù) B。這是 Android 系統(tǒng)中的一個(gè)多任務(wù)示例奴潘。
注:后臺可以同時(shí)運(yùn)行多個(gè)任務(wù)旧烧。但是,如果用戶同時(shí)運(yùn)行多個(gè)后臺任務(wù)画髓,則系統(tǒng)可能會(huì)開始銷毀后臺 Activity掘剪,以回收內(nèi)存資源,從而導(dǎo)致 Activity 狀態(tài)丟失奈虾。請參閱下面有關(guān)Activity 狀態(tài)的部分夺谁。
由于返回棧中的 Activity 永遠(yuǎn)不會(huì)重新排列,因此如果應(yīng)用允許用戶從多個(gè) Activity 中啟動(dòng)特定 Activity肉微,則會(huì)創(chuàng)建該 Activity 的新實(shí)例并推入堆棧中(而不是將 Activity 的任一先前實(shí)例置于頂部)匾鸥。 因此,應(yīng)用中的一個(gè) Activity 可能會(huì)多次實(shí)例化(即使 Activity 來自不同的任務(wù))碉纳,如圖 3 所示扫腺。因此,如果用戶使用“返回”按鈕向后導(dǎo)航村象,則會(huì)按 Activity 每個(gè)實(shí)例的打開順序顯示這些實(shí)例(每個(gè)實(shí)例的 UI 狀態(tài)各不相同)。 但是攒至,如果您不希望 Activity 多次實(shí)例化厚者,則可修改此行為。 具體操作方法將在后面的管理任務(wù)部分中討論迫吐。
Activity 和任務(wù)的默認(rèn)行為總結(jié)如下:
當(dāng) Activity A 啟動(dòng) Activity B 時(shí)库菲,Activity A 將會(huì)停止,但系統(tǒng)會(huì)保留其狀態(tài)(例如志膀,滾動(dòng)位置和已輸入表單中的文本)熙宇。如果用戶在處于 Activity B 時(shí)按“返回”按鈕,則 Activity A 將恢復(fù)其狀態(tài)溉浙,繼續(xù)執(zhí)行烫止。
用戶通過按“主頁”按鈕離開任務(wù)時(shí),當(dāng)前 Activity 將停止且其任務(wù)會(huì)進(jìn)入后臺戳稽。 系統(tǒng)將保留任務(wù)中每個(gè) Activity 的狀態(tài)馆蠕。如果用戶稍后通過選擇開始任務(wù)的啟動(dòng)器圖標(biāo)來恢復(fù)任務(wù),則任務(wù)將出現(xiàn)在前臺并恢復(fù)執(zhí)行堆棧頂部的 Activity。
如果用戶按“返回”按鈕互躬,則當(dāng)前 Activity 會(huì)從堆棧彈出并被銷毀播赁。 堆棧中的前一個(gè) Activity 恢復(fù)執(zhí)行。銷毀 Activity 時(shí)吼渡,系統(tǒng)不會(huì)保留該 Activity 的狀態(tài)容为。
即使來自其他任務(wù),Activity 也可以多次實(shí)例化寺酪。
保存 Activity 狀態(tài)
正如上文所述坎背,當(dāng) Activity 停止時(shí),系統(tǒng)的默認(rèn)行為會(huì)保留其狀態(tài)房维。 這樣一來沼瘫,當(dāng)用戶導(dǎo)航回到上一個(gè) Activity 時(shí),其用戶界面與用戶離開時(shí)一樣咙俩。 但是耿戚,在 Activity 被銷毀且必須重建時(shí),您可以而且應(yīng)當(dāng)主動(dòng)使用回調(diào)方法保留 Activity 的狀態(tài)阿趁。
系統(tǒng)停止您的一個(gè) Activity 時(shí)(例如膜蛔,新 Activity 啟動(dòng)或任務(wù)轉(zhuǎn)到前臺),如果系統(tǒng)需要回收系統(tǒng)內(nèi)存資源脖阵,則可能會(huì)完全銷毀該 Activity皂股。 發(fā)生這種情況時(shí),有關(guān)該 Activity 狀態(tài)的信息將會(huì)丟失命黔。如果發(fā)生這種情況呜呐,系統(tǒng)仍會(huì)知道該 Activity 存在于返回棧中,但是當(dāng)該 Activity 被置于堆棧頂部時(shí)悍募,系統(tǒng)一定會(huì)重建 Activity(而不是恢復(fù) Activity)蘑辑。 為了避免用戶的工作丟失,您應(yīng)主動(dòng)通過在 Activity 中實(shí)現(xiàn)onSaveInstanceState()回調(diào)方法來保留工作坠宴。
如需了解有關(guān)如何保存 Activity 狀態(tài)的詳細(xì)信息洋魂,請參閱Activity文檔。
管理任務(wù)
Android 管理任務(wù)和返回棧的方式(如上所述喜鼓,即:將所有連續(xù)啟動(dòng)的 Activity 放入同一任務(wù)和“后進(jìn)先出”堆棧中)非常適用于大多數(shù)應(yīng)用副砍,而您不必?fù)?dān)心 Activity 如何與任務(wù)關(guān)聯(lián)或者如何存在于返回棧中。 但是庄岖,您可能會(huì)決定要中斷正常行為豁翎。 也許您希望應(yīng)用中的 Activity 在啟動(dòng)時(shí)開始新任務(wù)(而不是放置在當(dāng)前任務(wù)中);或者隅忿,當(dāng)啟動(dòng) Activity 時(shí)谨垃,您希望將其現(xiàn)有實(shí)例上移一層(而不是在返回棧的頂部創(chuàng)建新實(shí)例)启搂;或者,您希望在用戶離開任務(wù)時(shí)刘陶,清除返回棧中除根 Activity 以外的所有其他 Activity胳赌。
通過使用清單文件元素中的屬性和傳遞給startActivity()的 Intent 中的標(biāo)志,您可以執(zhí)行所有這些操作以及其他操作匙隔。
您可以使用的主要 Intent 標(biāo)志包括:
在下文中,您將了解如何使用這些清單文件屬性和 Intent 標(biāo)志定義 Activity 與任務(wù)的關(guān)聯(lián)方式纷责,以及 Activity 在返回棧中的行為方式捍掺。
此外,我們還單獨(dú)介紹了有關(guān)如何在概覽屏幕中顯示和管理任務(wù)與 Activity 的注意事項(xiàng)再膳。 如需了解詳細(xì)信息挺勿,請參閱概覽屏幕。 通常喂柒,您應(yīng)該允許系統(tǒng)定義任務(wù)和 Activity 在概覽屏幕中的顯示方法不瓶,并且無需修改此行為。
注意:大多數(shù)應(yīng)用都不得中斷 Activity 和任務(wù)的默認(rèn)行為: 如果確定您的 Activity 必須修改默認(rèn)行為灾杰,當(dāng)使用“返回”按鈕從其他 Activity 和任務(wù)導(dǎo)航回到該 Activity 時(shí)蚊丐,請務(wù)必要謹(jǐn)慎并確保在啟動(dòng)期間測試該 Activity 的可用性。請確保測試導(dǎo)航行為是否有可能與用戶的預(yù)期行為沖突艳吠。
定義啟動(dòng)模式
啟動(dòng)模式允許您定義 Activity 的新實(shí)例如何與當(dāng)前任務(wù)關(guān)聯(lián)麦备。 您可以通過兩種方法定義不同的啟動(dòng)模式:
在清單文件中聲明 Activity 時(shí),您可以指定 Activity 在啟動(dòng)時(shí)應(yīng)該如何與任務(wù)關(guān)聯(lián)昭娩。
調(diào)用startActivity()時(shí)凛篙,可以在Intent中加入一個(gè)標(biāo)志,用于聲明新 Activity 如何(或是否)與當(dāng)前任務(wù)關(guān)聯(lián)栏渺。
因此呛梆,如果 Activity A 啟動(dòng) Activity B,則 Activity B 可以在其清單文件中定義它應(yīng)該如何與當(dāng)前任務(wù)關(guān)聯(lián)(如果可能)迈嘹,并且 Activity A 還可以請求 Activity B 應(yīng)該如何與當(dāng)前任務(wù)關(guān)聯(lián)。如果這兩個(gè) Activity 均定義 Activity B 應(yīng)該如何與任務(wù)關(guān)聯(lián)全庸,則 Activity A 的請求(如 Intent 中所定義)優(yōu)先級要高于 Activity B 的請求(如其清單文件中所定義)秀仲。
注:某些適用于清單文件的啟動(dòng)模式不可用作 Intent 標(biāo)志,同樣壶笼,某些可用作 Intent 標(biāo)志的啟動(dòng)模式無法在清單文件中定義神僵。
使用清單文件
在清單文件中聲明 Activity 時(shí),您可以使用元素的launchMode屬性指定 Activity 應(yīng)該如何與任務(wù)關(guān)聯(lián)覆劈。
launchMode屬性指定有關(guān)應(yīng)如何將 Activity 啟動(dòng)到任務(wù)中的指令保礼。您可以分配給launchMode屬性的啟動(dòng)模式共有四種:
"standard"(默認(rèn)模式)
默認(rèn)沛励。系統(tǒng)在啟動(dòng) Activity 的任務(wù)中創(chuàng)建 Activity 的新實(shí)例并向其傳送 Intent。Activity 可以多次實(shí)例化炮障,而每個(gè)實(shí)例均可屬于不同的任務(wù)目派,并且一個(gè)任務(wù)可以擁有多個(gè)實(shí)例。
"singleTop"
如果當(dāng)前任務(wù)的頂部已存在 Activity 的一個(gè)實(shí)例胁赢,則系統(tǒng)會(huì)通過調(diào)用該實(shí)例的onNewIntent()方法向其傳送 Intent企蹭,而不是創(chuàng)建 Activity 的新實(shí)例。Activity 可以多次實(shí)例化智末,而每個(gè)實(shí)例均可屬于不同的任務(wù)谅摄,并且一個(gè)任務(wù)可以擁有多個(gè)實(shí)例(但前提是位于返回棧頂部的 Activity 并不是 Activity 的現(xiàn)有實(shí)例)。
例如系馆,假設(shè)任務(wù)的返回棧包含根 Activity A 以及 Activity B送漠、C 和位于頂部的 D(堆棧是 A-B-C-D;D 位于頂部)由蘑。收到針對 D 類 Activity 的 Intent闽寡。如果 D 具有默認(rèn)的"standard"啟動(dòng)模式,則會(huì)啟動(dòng)該類的新實(shí)例纵穿,且堆棧會(huì)變成 A-B-C-D-D下隧。但是,如果 D 的啟動(dòng)模式是"singleTop"谓媒,則 D 的現(xiàn)有實(shí)例會(huì)通過onNewIntent()接收 Intent淆院,因?yàn)樗挥诙褩5捻敳浚欢褩H詾?A-B-C-D句惯。但是土辩,如果收到針對 B 類 Activity 的 Intent,則會(huì)向堆棧添加 B 的新實(shí)例抢野,即便其啟動(dòng)模式為"singleTop"也是如此拷淘。
注:為某個(gè) Activity 創(chuàng)建新實(shí)例時(shí),用戶可以按“返回”按鈕返回到前一個(gè) Activity指孤。 但是启涯,當(dāng) Activity 的現(xiàn)有實(shí)例處理新 Intent 時(shí),則在新 Intent 到達(dá)onNewIntent()之前恃轩,用戶無法按“返回”按鈕返回到 Activity 的狀態(tài)结洼。
"singleTask"
系統(tǒng)創(chuàng)建新任務(wù)并實(shí)例化位于新任務(wù)底部的 Activity。但是叉跛,如果該 Activity 的一個(gè)實(shí)例已存在于一個(gè)單獨(dú)的任務(wù)中松忍,則系統(tǒng)會(huì)通過調(diào)用現(xiàn)有實(shí)例的onNewIntent()方法向其傳送 Intent,而不是創(chuàng)建新實(shí)例筷厘。一次只能存在 Activity 的一個(gè)實(shí)例鸣峭。
注:盡管 Activity 在新任務(wù)中啟動(dòng)宏所,但是用戶按“返回”按鈕仍會(huì)返回到前一個(gè) Activity。
"singleInstance".
與"singleTask"相同摊溶,只是系統(tǒng)不會(huì)將任何其他 Activity 啟動(dòng)到包含實(shí)例的任務(wù)中爬骤。該 Activity 始終是其任務(wù)唯一僅有的成員;由此 Activity 啟動(dòng)的任何 Activity 均在單獨(dú)的任務(wù)中打開更扁。
我們再來看另一示例盖腕,Android 瀏覽器應(yīng)用聲明網(wǎng)絡(luò)瀏覽器 Activity 應(yīng)始終在其自己的任務(wù)中打開(通過在元素中指定singleTask啟動(dòng)模式)。這意味著浓镜,如果您的應(yīng)用發(fā)出打開 Android 瀏覽器的 Intent溃列,則其 Activity 與您的應(yīng)用位于不同的任務(wù)中。相反膛薛,系統(tǒng)會(huì)為瀏覽器啟動(dòng)新任務(wù)听隐,或者如果瀏覽器已有任務(wù)正在后臺運(yùn)行,則會(huì)將該任務(wù)上移一層以處理新 Intent哄啄。
無論 Activity 是在新任務(wù)中啟動(dòng)雅任,還是在與啟動(dòng) Activity 相同的任務(wù)中啟動(dòng),用戶按“返回”按鈕始終會(huì)轉(zhuǎn)到前一個(gè) Activity咨跌。 但是沪么,如果啟動(dòng)指定singleTask啟動(dòng)模式的 Activity,則當(dāng)某后臺任務(wù)中存在該 Activity 的實(shí)例時(shí)锌半,整個(gè)任務(wù)都會(huì)轉(zhuǎn)移到前臺禽车。此時(shí),返回棧包括上移到堆棧頂部的任務(wù)中的所有 Activity刊殉。 圖 4 顯示了這種情況殉摔。
如需了解有關(guān)在清單文件中使用啟動(dòng)模式的詳細(xì)信息,請參閱元素文檔遍膜,其中更詳細(xì)地討論了launchMode屬性和可接受的值碗硬。
注:使用launchMode屬性為 Activity 指定的行為可由 Intent 附帶的 Activity 啟動(dòng)標(biāo)志替代,下文將對此進(jìn)行討論瓢颅。
使用 Intent 標(biāo)志
啟動(dòng) Activity 時(shí)恩尾,您可以通過在傳遞給startActivity()的 Intent 中加入相應(yīng)的標(biāo)志,修改 Activity 與其任務(wù)的默認(rèn)關(guān)聯(lián)方式惜索√厮瘢可用于修改默認(rèn)行為的標(biāo)志包括:
在新任務(wù)中啟動(dòng) Activity剃浇。如果已為正在啟動(dòng)的 Activity 運(yùn)行任務(wù)巾兆,則該任務(wù)會(huì)轉(zhuǎn)到前臺并恢復(fù)其最后狀態(tài)猎物,同時(shí) Activity 會(huì)在onNewIntent()中收到新 Intent。
正如前文所述角塑,這會(huì)產(chǎn)生與"singleTask"launchMode值相同的行為蔫磨。
如果正在啟動(dòng)的 Activity 是當(dāng)前 Activity(位于返回棧的頂部),則 現(xiàn)有實(shí)例會(huì)接收對onNewIntent()的調(diào)用圃伶,而不是創(chuàng)建 Activity 的新實(shí)例堤如。
正如前文所述,這會(huì)產(chǎn)生與"singleTop"launchMode值相同的行為窒朋。
如果正在啟動(dòng)的 Activity 已在當(dāng)前任務(wù)中運(yùn)行搀罢,則會(huì)銷毀當(dāng)前任務(wù)頂部的所有 Activity,并通過onNewIntent()將此 Intent 傳遞給 Activity 已恢復(fù)的實(shí)例(現(xiàn)在位于頂部)侥猩,而不是啟動(dòng)該 Activity 的新實(shí)例榔至。
產(chǎn)生這種行為的launchMode屬性沒有值。
FLAG_ACTIVITY_CLEAR_TOP通常與FLAG_ACTIVITY_NEW_TASK結(jié)合使用欺劳。一起使用時(shí)唧取,通過這些標(biāo)志,可以找到其他任務(wù)中的現(xiàn)有 Activity划提,并將其放入可從中響應(yīng) Intent 的位置枫弟。
注:如果指定 Activity 的啟動(dòng)模式為"standard",則該 Activity 也會(huì)從堆棧中移除鹏往,并在其位置啟動(dòng)一個(gè)新實(shí)例淡诗,以便處理傳入的 Intent。 這是因?yàn)楫?dāng)啟動(dòng)模式為"standard"時(shí)掸犬,將始終為新 Intent 創(chuàng)建新實(shí)例袜漩。
處理關(guān)聯(lián)
“關(guān)聯(lián)”指示 Activity 優(yōu)先屬于哪個(gè)任務(wù)。默認(rèn)情況下湾碎,同一應(yīng)用中的所有 Activity 彼此關(guān)聯(lián)宙攻。 因此,默認(rèn)情況下介褥,同一應(yīng)用中的所有 Activity 優(yōu)先位于相同任務(wù)中座掘。 不過,您可以修改 Activity 的默認(rèn)關(guān)聯(lián)柔滔。 在不同應(yīng)用中定義的 Activity 可以共享關(guān)聯(lián)溢陪,或者可為在同一應(yīng)用中定義的 Activity 分配不同的任務(wù)關(guān)聯(lián)。
可以使用元素的taskAffinity屬性修改任何給定 Activity 的關(guān)聯(lián)睛廊。
taskAffinity屬性取字符串值形真,該值必須不同于在元素中聲明的默認(rèn)軟件包名稱,因?yàn)橄到y(tǒng)使用該名稱標(biāo)識應(yīng)用的默認(rèn)任務(wù)關(guān)聯(lián)超全。
在兩種情況下咆霜,關(guān)聯(lián)會(huì)起作用:
啟動(dòng) Activity 的 Intent 包含FLAG_ACTIVITY_NEW_TASK標(biāo)志邓馒。
默認(rèn)情況下,新 Activity 會(huì)啟動(dòng)到調(diào)用startActivity()的 Activity 任務(wù)中蛾坯。它將推入與調(diào)用方相同的返回棧光酣。 但是蚕苇,如果傳遞給startActivity()的 Intent 包含FLAG_ACTIVITY_NEW_TASK標(biāo)志河哑,則系統(tǒng)會(huì)尋找其他任務(wù)來儲(chǔ)存新 Activity娇斩。這通常是新任務(wù)脐帝,但未做強(qiáng)制要求誊稚。 如果現(xiàn)有任務(wù)與新 Activity 具有相同關(guān)聯(lián)铛绰,則會(huì)將 Activity 啟動(dòng)到該任務(wù)中浙垫。 否則兜畸,將開始新任務(wù)呈驶。
如果此標(biāo)志導(dǎo)致 Activity 開始新任務(wù)胆萧,且用戶按“主頁”按鈕離開,則必須為用戶提供導(dǎo)航回任務(wù)的方式俐东。 有些實(shí)體(如通知管理器)始終在外部任務(wù)中啟動(dòng) Activity跌穗,而從不作為其自身的一部分啟動(dòng) Activity,因此它們始終將FLAG_ACTIVITY_NEW_TASK放入傳遞給startActivity()的 Intent 中虏辫。請注意蚌吸,如果 Activity 能夠由可以使用此標(biāo)志的外部實(shí)體調(diào)用,則用戶可以通過獨(dú)立方式返回到啟動(dòng)的任務(wù)砌庄,例如羹唠,使用啟動(dòng)器圖標(biāo)(任務(wù)的根 Activity 具有CATEGORY_LAUNCHERIntent 過濾器;請參閱下面的啟動(dòng)任務(wù)部分)娄昆。
Activity 將其allowTaskReparenting屬性設(shè)置為"true"佩微。
在這種情況下,Activity 可以從其啟動(dòng)的任務(wù)移動(dòng)到與其具有關(guān)聯(lián)的任務(wù)(如果該任務(wù)出現(xiàn)在前臺)萌焰。
例如哺眯,假設(shè)將報(bào)告所選城市天氣狀況的 Activity 定義為旅行應(yīng)用的一部分。 它與同一應(yīng)用中的其他 Activity 具有相同的關(guān)聯(lián)(默認(rèn)應(yīng)用關(guān)聯(lián))扒俯,并允許利用此屬性重定父級奶卓。當(dāng)您的一個(gè) Activity 啟動(dòng)天氣預(yù)報(bào) Activity 時(shí),它最初所屬的任務(wù)與您的 Activity 相同撼玄。 但是夺姑,當(dāng)旅行應(yīng)用的任務(wù)出現(xiàn)在前臺時(shí),系統(tǒng)會(huì)將天氣預(yù)報(bào) Activity 重新分配給該任務(wù)并顯示在其中掌猛。
提示:如果從用戶的角度來看盏浙,一個(gè).apk文件包含多個(gè)“應(yīng)用”,則您可能需要使用taskAffinity屬性將不同關(guān)聯(lián)分配給與每個(gè)“應(yīng)用”相關(guān)的 Activity。
清理返回棧
如果用戶長時(shí)間離開任務(wù)废膘,則系統(tǒng)會(huì)清除所有 Activity 的任務(wù)辣往,根 Activity 除外。 當(dāng)用戶再次返回到任務(wù)時(shí)殖卑,僅恢復(fù)根 Activity。系統(tǒng)這樣做的原因是坊萝,經(jīng)過很長一段時(shí)間后孵稽,用戶可能已經(jīng)放棄之前執(zhí)行的操作,返回到任務(wù)是要開始執(zhí)行新的操作十偶。
您可以使用下列幾個(gè) Activity 屬性修改此行為:
如果在任務(wù)的根 Activity 中將此屬性設(shè)置為"true"菩鲜,則不會(huì)發(fā)生剛才所述的默認(rèn)行為。即使在很長一段時(shí)間后惦积,任務(wù)仍將所有 Activity 保留在其堆棧中接校。
如果在任務(wù)的根 Activity 中將此屬性設(shè)置為"true",則每當(dāng)用戶離開任務(wù)然后返回時(shí)狮崩,系統(tǒng)都會(huì)將堆棧清除到只剩下根 Activity蛛勉。 換而言之,它與alwaysRetainTaskState正好相反睦柴。 即使只離開任務(wù)片刻時(shí)間诽凌,用戶也始終會(huì)返回到任務(wù)的初始狀態(tài)。
此屬性類似于clearTaskOnLaunch坦敌,但它對單個(gè) Activity 起作用侣诵,而非整個(gè)任務(wù)。 此外狱窘,它還有可能會(huì)導(dǎo)致任何 Activity 停止杜顺,包括根 Activity。 設(shè)置為"true"時(shí)蘸炸,Activity 仍是任務(wù)的一部分躬络,但是僅限于當(dāng)前會(huì)話。如果用戶離開然后返回任務(wù)搭儒,則任務(wù)將不復(fù)存在洗鸵。
啟動(dòng)任務(wù)
通過為 Activity 提供一個(gè)以"android.intent.action.MAIN"為指定操作、以"android.intent.category.LAUNCHER"為指定類別的 Intent 過濾器仗嗦,您可以將 Activity 設(shè)置為任務(wù)的入口點(diǎn)膘滨。 例如:
...
此類 Intent 過濾器會(huì)使 Activity 的圖標(biāo)和標(biāo)簽顯示在應(yīng)用啟動(dòng)器中,讓用戶能夠啟動(dòng) Activity 并在啟動(dòng)之后隨時(shí)返回到創(chuàng)建的任務(wù)中稀拐。
第二個(gè)功能非常重要:用戶必須能夠在離開任務(wù)后火邓,再使用此 Activity 啟動(dòng)器返回該任務(wù)。 因此,只有在 Activity 具有ACTION_MAIN和CATEGORY_LAUNCHER過濾器時(shí)铲咨,才應(yīng)該使用將 Activity 標(biāo)記為“始終啟動(dòng)任務(wù)”的兩種啟動(dòng)模式躲胳,即"singleTask"和"singleInstance"。例如纤勒,我們可以想像一下如果缺少過濾器會(huì)發(fā)生什么情況: Intent 啟動(dòng)一個(gè)"singleTask"Activity坯苹,從而啟動(dòng)一個(gè)新任務(wù),并且用戶花了些時(shí)間處理該任務(wù)摇天。然后粹湃,用戶按“主頁”按鈕。 任務(wù)現(xiàn)已發(fā)送到后臺泉坐,而且不可見∥現(xiàn)在,用戶無法返回到任務(wù)腕让,因?yàn)樵撊蝿?wù)未顯示在應(yīng)用啟動(dòng)器中孤钦。
如果您并不想用戶能夠返回到 Activity,對于這些情況纯丸,請將元素的finishOnTaskLaunch設(shè)置為"true"(請參閱清理堆棧)偏形。
有關(guān)如何在概覽屏幕中顯示和管理任務(wù)與 Activity 的更多信息,請參閱概覽屏幕觉鼻。