在總結Activity的啟動模式前,我們先來認真一下android中的任務與返回棧模式。
什么是任務?
Android中的任務是指在執行特定作業時與用戶交互的一系列 Activity。 這些 Activity 按照各自的打開順序排列在堆棧(即返回棧)中。如圖,即是一個完整的任務棧流程。
Activity 和任務的默認行為總結如下:
1.當 Activity A 啟動 Activity B 時,Activity A 將會停止,但系統會保留其狀態(例如,滾動位置和已輸入表單中的文本)。如果用戶在處于 Activity B 時按“返回”按鈕,則 Activity A 將恢復其狀態,繼續執行。
2.用戶通過按“主頁”按鈕離開任務時,當前 Activity 將停止且其任務會進入后臺。 系統將保留任務中每個 Activity 的狀態。如果用戶稍后通過選擇開始任務的啟動器圖標來恢復任務,則任務將出現在前臺并恢復執行堆棧頂部的 Activity。
3.如果用戶按“返回”按鈕,則當前 Activity 會從堆棧彈出并被銷毀。 堆棧中的前一個 Activity 恢復執行。銷毀 Activity 時,系統不會保留該 Activity 的狀態。
android的多任務模式中,任務的狀態與行為各有不同,那我們如何去管理任務,并且控制任務內部元素的狀態呢? 這就講到了Activity的啟動模式、
Activity的啟動模式
1.定義啟動模式
? ? Activity的啟動模式定義有兩種, 一種在AndroidManifast.xml中定義launchMode屬性,一種即在startActivity的Intent參數中聲明新 Activity 如何(或是否)與當前任務關聯。 如果一個Activity在清單中定義了其關聯方式,并且startActivity中的Intent也已經聲明,則Intent中定義的優先級要高于清單文件。
2.啟動模式介紹
? ?清單文件中的屬性:
? ? ? ? "standard":?默認。系統在啟動 Activity 的任務中創建 Activity 的新實例并向其傳送 Intent。Activity 可以多次實例化,而每個實例均可屬于不同的任務,并且一個任務可以擁有多個實例。
? ? ? ? "singleTop":如果當前任務的頂部已存在 Activity 的一個實例,則系統會通過調用該實例的onNewIntent()方法向其傳送 Intent,而不是創建 Activity 的新實例。Activity 可以多次實例化,而每個實例均可屬于不同的任務,并且一個任務可以擁有多個實例(但前提是位于返回棧頂部的 Activity 并不是 Activity 的現有實例)。
例如,假設任務的返回棧包含根 Activity A 以及 Activity B、C 和位于頂部的 D(堆棧是 A-B-C-D;D 位于頂部)。收到針對 D 類 Activity 的 Intent。如果 D 具有默認的"standard"啟動模式,則會啟動該類的新實例,且堆棧會變成 A-B-C-D-D。但是,如果 D 的啟動模式是"singleTop",則 D 的現有實例會通過onNewIntent()接收 Intent,因為它位于堆棧的頂部;而堆棧仍為 A-B-C-D。但是,如果收到針對 B 類 Activity 的 Intent,則會向堆棧添加 B 的新實例堆棧變成了A-B-C-D-B,即便其啟動模式為"singleTop"也是如此。
? ? ? ?"singleTask" :系統創建新任務并實例化位于新任務底部的 Activity。但是,如果該 Activity 的一個實例已存在于一個單獨的任務中,則系統會通過調用現有實例的onNewIntent()方法向其傳送 Intent,而不是創建新實例。一次只能存在 Activity 的一個實例。?注:盡管 Activity 在新任務中啟動,但是用戶按“返回”按鈕仍會返回到前一個 Activity。
? ? ? "singleInstance":與"singleTask"相同,只是系統不會將任何其他 Activity 啟動到包含實例的任務中。該 Activity 始終是其任務唯一僅有的成員;由此 Activity 啟動的任何 Activity 均在單獨的任務中打開。
Intent中的參數:
? ? FLAG_ACTIVITY_NEW_TASK?: 同清單屬性中的singleTask
? ? FLAG_ACTIVITY_SINGLE_TOP?: 同清單屬性中的singleTop
? ??FLAG_ACTIVITY_CLEAR_TOP : 如果正在啟動的 Activity 已在當前任務中運行,則會銷毀當前任務頂部的所有 Activity,并通過onNewIntent()將此 Intent 傳遞給 Activity 已恢復的實例(現在位于頂部),而不是啟動該 Activity 的新實例。