本文大部分翻譯自 《Android “launchMode” (Visualized)》, 並結合自己的理解在
SingleInstance
中新增了補充內容
啟動模式
是很重要的一塊知識點,每位安卓開發都應該瞭解它是如何運作的。大部分的開發者(包括我自己)認為我們已經知道了如何來使用 啟動模式
。但是其實我們錯了。不僅僅是知道將 Activity 設定為 SingleTask
來防止重複例項化就足夠了,雖然大部分情況下這已經解決了我們的業務需求。但是我們真的瞭解當我們將一個 Activity 設定為 SingleTask
時,它是如何影響 Activity 任務棧內其他 Activites 的嗎?
本文將圖文的模式來講解 4 中啟動模式
的作用及區別。首先需要來講解以下圖片的作用來幫助你更容易理解下面的內容
綠色代表在 Activity 任務棧中建立了一個新的 Activity 例項
黃色則代表複用了之前建立的 Activity 例項,但是該 Activity 的onNewIntent()
方法將會被呼叫
Standard 啟動模式講解
如果在
AndroidManifest.xml
中將 Activity B 的啟動模式設定為 Standard,不管任務棧內是否已經存在 Activity B 的例項,當啟動 Activity B 時,都會建立一個嶄新的 Activity B 位於任務棧頂
SingleTask 模式講解
如果在
AndroidManifest.xml
中將 Activity C 的啟動模式設定為 SingleTask,如果此時任務棧內已經存在 Activity C 的例項且未位於棧頂,當啟動 Activity C 時,會將 Activity C 上方的例項全部出棧讓其位於任務棧頂並 Activity C 中的onNewIntent()
方法會被呼叫
如果在
AndroidManifest.xml
中將 Activity C 的啟動模式設定為 SingleTask,並且此時任務棧內並不存在 Activity C 的例項,當啟動 Activity C 時,會建立一個嶄新的 Activity C 例項在棧頂
SingleTop 啟動模式講解
如果在
AndroidManifest.xml
中將 Activity D 的啟動模式設定為 SingleTop 並且任務棧記憶體在 Activity D 例項且位於棧頂時,當啟動 Activity D 時,會複用之前建立的 Activity D 的例項,並且onNewIntent()
方法被呼叫
如果在
AndroidManifest.xml
中將 Activity D 的啟動模式設定為 SingleTop 並且任務棧內並不存在 Activity D 的例項時,當啟動 Activity D 時,會建立一個嶄新的 Activity D 例項在棧頂
如果在
AndroidManifest.xml
中將 Activity D 的啟動模式設定為 SingleTop 並且任務棧記憶體在 Activity D 的例項但其例項未在棧頂時,當啟動 Activity D 時,會再次建立一個嶄新的 Activity D 例項在棧頂
SingleInstance 模式講解
如果在
AndroidManifest.xml
中將 Activity E 的啟動模式設定為 SingleInstance,並且任務棧內不存在 Activity E 的例項,當啟動 Activity E 時,會在建立一個新的任務棧,並且棧內只有 Activity E 一個例項
如果此時基於上面的任務棧,從 Activity D 中開啟一個啟動模式為 Standard
的 Activity F,那任務棧會發生什麼樣的變化呢?請看下圖
此時 Activity E 依舊會獨立的存在於自己的任務棧中,而新建立的 Activity F 將會和 Activity D 位於相同的任務棧的棧頂
如果啟動模式為
SingleInstance
的 Activity E 已經獨立存在於自己的任務棧中,此時再啟動 Activity E, 則會複用已經建立的 Activity E 的例項,並且 Activity E 的onNewIntent()
方法被呼叫
如果基於上面的任務棧,從 Activity E 中開啟一個啟動模式為 Standard
的 Activity F,那任務棧會發什麼樣的變化呢,請看下圖
因為
singleInstance
的屬性是禁止與其他 Activities 共享任務棧,所以啟動模式為SingleInstance
的 Activity 啟動其他 Activity 時會預設帶有FLAG_ACTIVITY_NEW_TASK
屬性。所以 Activity E 啟動 Activity F 後,最後會存在三個任務棧,Activity F 會單獨存在於一個任務棧中