[文章內(nèi)容來自Developers]
應(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)在前臺(tái)亡鼠。 如果應(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)先出”對(duì)象結(jié)構(gòu)運(yùn)行牡属。 圖 1 通過時(shí)間線顯示 Activity 之間的進(jìn)度以及每個(gè)時(shí)間點(diǎn)的當(dāng)前返回棧票堵,直觀呈現(xiàn)了這種行為。
如果用戶繼續(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)到“后臺(tái)”宙搬。 盡管在后臺(tái)時(shí)笨腥,該任務(wù)中的所有 Activity 全部停止,但是任務(wù)的返回棧仍舊不變害淤,也就是說扇雕,當(dāng)另一個(gè)任務(wù)發(fā)生時(shí),該任務(wù)僅僅失去焦點(diǎn)而已窥摄,如圖 2 中所示镶奉。然后,任務(wù)可以返回到“前臺(tái)”崭放,用戶就能夠回到離開時(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)入后臺(tái)。新應(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)在前臺(tái),其堆棧中的所有三個(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ù)示例彻桃。
注:后臺(tái)可以同時(shí)運(yùn)行多個(gè)任務(wù)。但是仅父,如果用戶同時(shí)運(yùn)行多個(gè)后臺(tái)任務(wù)叛薯,則系統(tǒng)可能會(huì)開始銷毀后臺(tái) Activity浑吟,以回收內(nèi)存資源笙纤,從而導(dǎo)致 Activity 狀態(tài)丟失。請(qǐng)參閱下面有關(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ái)钦铺。 系統(tǒng)將保留任務(wù)中每個(gè) Activity 的狀態(tài)。如果用戶稍后通過選擇開始任務(wù)的啟動(dòng)器圖標(biāo)來恢復(fù)任務(wù)欧漱,則任務(wù)將出現(xiàn)在前臺(tái)并恢復(fù)執(zhí)行堆棧頂部的 Activity职抡。
如果用戶按“返回”按鈕,則當(dāng)前 Activity 會(huì)從堆棧彈出并被銷毀误甚。 堆棧中的前一個(gè) Activity 恢復(fù)執(zhí)行缚甩。銷毀 Activity 時(shí)谱净,系統(tǒng)不會(huì)保留該 Activity 的狀態(tài)。 - 即使來自其他任務(wù)擅威,Activity 也可以多次實(shí)例化壕探。
導(dǎo)航設(shè)計(jì)
如需了解有關(guān) Android 應(yīng)用導(dǎo)航工作方式的詳細(xì)信息,請(qǐng)閱讀 Android 設(shè)計(jì)的導(dǎo)航指南郊丛。
保存 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ái)),如果系統(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)方法來保留工作茸歧。
管理任務(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。
通過使用 <activity>清單文件元素中的屬性和傳遞給 startActivity()的 Intent 中的標(biāo)志喉誊,您可以執(zhí)行所有這些操作以及其他操作邀摆。
在這一方面,您可以使用的主要 <activity>屬性包括:
taskAffinity
launchMode
allowTaskReparenting
clearTaskOnLaunch
alwaysRetainTaskState
finishOnTaskLaunch
您可以使用的主要 Intent 標(biāo)志包括:
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_SINGLE_TOP
在下文中伍茄,您將了解如何使用這些清單文件屬性和 Intent 標(biāo)志定義 Activity 與任務(wù)的關(guān)聯(lián)方式栋盹,以及 Activity 在返回棧中的行為方式。
此外敷矫,我們還單獨(dú)介紹了有關(guān)如何在概覽屏幕中顯示和管理任務(wù)與 Activity 的注意事項(xiàng)例获。 通常,您應(yīng)該允許系統(tǒng)定義任務(wù)和 Activity 在概覽屏幕中的顯示方法曹仗,并且無需修改此行為榨汤。
注意:大多數(shù)應(yīng)用都不得中斷 Activity 和任務(wù)的默認(rèn)行為: 如果確定您的 Activity 必須修改默認(rèn)行為,當(dāng)使用“返回”按鈕從其他 Activity 和任務(wù)導(dǎo)航回到該 Activity 時(shí)整葡,請(qǐng)務(wù)必要謹(jǐn)慎并確保在啟動(dòng)期間測(cè)試該 Activity 的可用性件余。請(qǐng)確保測(cè)試導(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)旬渠。
使用 Intent 標(biāo)志調(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 還可以請(qǐng)求 Activity B 應(yīng)該如何與當(dāng)前任務(wù)關(guān)聯(lián)岳颇。如果這兩個(gè) Activity 均定義 Activity B 應(yīng)該如何與任務(wù)關(guān)聯(lián),則 Activity A 的請(qǐng)求(如 Intent 中所定義)優(yōu)先級(jí)要高于 Activity B 的請(qǐng)求(如其清單文件中所定義)颅湘。
注:某些適用于清單文件的啟動(dòng)模式不可用作 Intent 標(biāo)志话侧,同樣,某些可用作 Intent 標(biāo)志的啟動(dòng)模式無法在清單文件中定義闯参。
使用清單文件
在清單文件中聲明 Activity 時(shí)瞻鹏,您可以使用 <activity>元素的 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 位于頂部)。收到針對(duì) 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。但是胡本,如果收到針對(duì) 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ù)中打開。
我們?cè)賮砜戳硪皇纠钥睿珹ndroid 瀏覽器應(yīng)用聲明網(wǎng)絡(luò)瀏覽器 Activity 應(yīng)始終在其自己的任務(wù)中打開(通過在 <activity>元素中指定 singleTask啟動(dòng)模式)课兄。這意味著,如果您的應(yīng)用發(fā)出打開 Android 瀏覽器的 Intent晨继,則其 Activity 與您的應(yīng)用位于不同的任務(wù)中烟阐。相反,系統(tǒng)會(huì)為瀏覽器啟動(dòng)新任務(wù)紊扬,或者如果瀏覽器已有任務(wù)正在后臺(tái)運(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)某后臺(tái)任務(wù)中存在該 Activity 的實(shí)例時(shí),整個(gè)任務(wù)都會(huì)轉(zhuǎn)移到前臺(tái)藏鹊。此時(shí)润讥,返回棧包括上移到堆棧頂部的任務(wù)中的所有 Activity。 圖 4 顯示了這種情況伙判。
如需了解有關(guān)在清單文件中使用啟動(dòng)模式的詳細(xì)信息,請(qǐng)參閱 <activity>元素文檔甫煞,其中更詳細(xì)地討論了 launchMode
屬性和可接受的值菇曲。
注:使用 launchMode屬性為 Activity 指定的行為可由 Intent 附帶的 Activity 啟動(dòng)標(biāo)志替代,下文將對(duì)此進(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)志包括:
FLAG_ACTIVITY_NEW_TASK
在新任務(wù)中啟動(dòng) Activity。如果已為正在啟動(dòng)的 Activity 運(yùn)行任務(wù)萧朝,則該任務(wù)會(huì)轉(zhuǎn)到前臺(tái)并恢復(fù)其最后狀態(tài)岔留,同時(shí) Activity 會(huì)在onNewIntent()中收到新 Intent。正如前文所述检柬,這會(huì)產(chǎn)生與 "singleTask"launchMode值相同的行為献联。
FLAG_ACTIVITY_SINGLE_TOP
如果正在啟動(dòng)的 Activity 是當(dāng)前 Activity(位于返回棧的頂部),則 現(xiàn)有實(shí)例會(huì)接收對(duì) onNewIntent()的調(diào)用,而不是創(chuàng)建 Activity 的新實(shí)例里逆。正如前文所述进胯,這會(huì)產(chǎn)生與 "singleTop"
launchMode值相同的行為。
FLAG_ACTIVITY_CLEAR_TOP
如果正在啟動(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)椅野。
可以使用 <activity>元素的 taskAffinity屬性修改任何給定 Activity 的關(guān)聯(lián)。
taskAffinity屬性取字符串值籍胯,該值必須不同于在[<manifest>元素中聲明的默認(rèn)軟件包名稱竟闪,因?yàn)橄到y(tǒng)使用該名稱標(biāo)識(shí)應(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 中土思。請(qǐng)注意务热,如果 Activity 能夠由可以使用此標(biāo)志的外部實(shí)體調(diào)用,則用戶可以通過獨(dú)立方式返回到啟動(dòng)的任務(wù)己儒,例如崎岂,使用啟動(dòng)器圖標(biāo)(任務(wù)的根 Activity 具有 CATEGORY_LAUNCHER Intent 過濾器;)闪湾。Activity 將其[allowTaskReparenting屬性設(shè)置為 "true"
冲甘。在這種情況下,Activity 可以從其啟動(dòng)的任務(wù)移動(dòng)到與其具有關(guān)聯(lián)的任務(wù)(如果該任務(wù)出現(xiàn)在前臺(tái))途样。
例如江醇,假設(shè)將報(bào)告所選城市天氣狀況的 Activity 定義為旅行應(yīng)用的一部分。 它與同一應(yīng)用中的其他 Activity 具有相同的關(guān)聯(lián)(默認(rèn)應(yīng)用關(guān)聯(lián))何暇,并允許利用此屬性重定父級(jí)嫁审。當(dāng)您的一個(gè) Activity 啟動(dòng)天氣預(yù)報(bào) Activity 時(shí),它最初所屬的任務(wù)與您的 Activity 相同赖晶。 但是,當(dāng)旅行應(yīng)用的任務(wù)出現(xiàn)在前臺(tái)時(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胳嘲。
清理返回棧
如果用戶長(zhǎng)時(shí)間離開任務(wù),則系統(tǒng)會(huì)清除所有 Activity 的任務(wù)扣草,根 Activity 除外了牛。 當(dāng)用戶再次返回到任務(wù)時(shí)颜屠,僅恢復(fù)根 Activity。系統(tǒng)這樣做的原因是鹰祸,經(jīng)過很長(zhǎng)一段時(shí)間后甫窟,用戶可能已經(jīng)放棄之前執(zhí)行的操作,返回到任務(wù)是要開始執(zhí)行新的操作蛙婴。
您可以使用下列幾個(gè) Activity 屬性修改此行為:
alwaysRetainTaskState
如果在任務(wù)的根 Activity 中將此屬性設(shè)置為 "true"粗井,則不會(huì)發(fā)生剛才所述的默認(rèn)行為。即使在很長(zhǎng)一段時(shí)間后街图,任務(wù)仍將所有 Activity 保留在其堆棧中浇衬。
clearTaskOnLaunch
如果在任務(wù)的根 Activity 中將此屬性設(shè)置為 "true"
,則每當(dāng)用戶離開任務(wù)然后返回時(shí)餐济,系統(tǒng)都會(huì)將堆棧清除到只剩下根 Activity耘擂。 換而言之,它與 alwaysRetainTaskState正好相反絮姆。 即使只離開任務(wù)片刻時(shí)間醉冤,用戶也始終會(huì)返回到任務(wù)的初始狀態(tài)。
finishOnTaskLaunch
此屬性類似于 clearTaskOnLaunch滚朵,但它對(duì)單個(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)倔喂。 例如:
<activity ... >
<intent-filter ... >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
...
</activity>
此類 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ā)送到后臺(tái)渔期,而且不可見≡讼牛現(xiàn)在,用戶無法返回到任務(wù)疯趟,因?yàn)樵撊蝿?wù)未顯示在應(yīng)用啟動(dòng)器中拘哨。
如果您并不想用戶能夠返回到 Activity,對(duì)于這些情況信峻,請(qǐng)將 <activity>元素的 finishOnTaskLaunch設(shè)置為 "true"倦青。