Activity啟動(dòng)模式

任務(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)了這種行為。


圖一顯示任務(wù)中的每個(gè)新 Activity 如何向返回棧添加項(xiàng)目。

用戶按“返回”按鈕時(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ù)存在。

圖 2.兩個(gè)任務(wù):任務(wù) B 在前臺接收用戶交互,而任務(wù) A 則在后臺等待恢復(fù)。


圖 3.一個(gè) Activity 將多次實(shí)例化。

任務(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í)行所有這些操作以及其他操作。

在這一方面,您可以使用的主要屬性包括:

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)。 如需了解詳細(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)。

使用 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 還可以請求 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 顯示了這種情況。


圖 4.顯示如何將啟動(dòng)模式為“singleTask”的 Activity 添加到返回棧。 如果 Activity 已經(jīng)是某個(gè)擁有自己的返回棧的后臺任務(wù)的一部分,則整個(gè)返回棧也會(huì)上移到當(dāng)前任務(wù)的頂部。

如需了解有關(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)志包括:

FLAG_ACTIVITY_NEW_TASK

在新任務(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值相同的行為。

FLAG_ACTIVITY_SINGLE_TOP

如果正在啟動(dòng)的 Activity 是當(dāng)前 Activity(位于返回棧的頂部),則 現(xiàn)有實(shí)例會(huì)接收對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)。

可以使用元素的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 屬性修改此行為:

alwaysRetainTaskState

如果在任務(wù)的根 Activity 中將此屬性設(shè)置為"true",則不會(huì)發(fā)生剛才所述的默認(rèn)行為。即使在很長一段時(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,但它對單個(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_MAINCATEGORY_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 的更多信息,請參閱概覽屏幕

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,646評論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,595評論 3 418
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,560評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,035評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,814評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,224評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,301評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,444評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,988評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,804評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,998評論 1 370
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,544評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,237評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,665評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,927評論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,706評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,993評論 2 374

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