Activity啟動模式解析

主要內(nèi)容

Activity是android的四大組件之一,可以說是我們android開發(fā)中最常用的技術(shù)之一。有關(guān)activity的知識點非常多,本文要介紹的是activity的四大啟動模式。四大啟動模式分別是standard(這是我們最常用的也是默認的一種啟動方式)、singleTop、singleTask、singleInstance。接下來我們將分別介紹這四大啟動模式以及他們的應用場景。


?任務(wù)和返回棧

在學習啟動模式之前,我們需要先了解一下任務(wù)和返回棧的知識,應用通常包含多個Activity。每個 Activity 均應圍繞用戶可以執(zhí)行的特定操作設(shè)計,并且能夠啟動其他 Activity。
任務(wù)是指在執(zhí)行特定作業(yè)時與用戶交互的一系列 Activity。 這些 Activity 按照各自的打開順序排列在堆棧(即“返回棧”)中。
設(shè)備主屏幕是大多數(shù)任務(wù)的起點。當用戶觸摸應用啟動器中的圖標(或主屏幕上的快捷鍵)時,該應用的任務(wù)將出現(xiàn)在前臺。 如果應用不存在任務(wù)(應用最近未曾使用),則會創(chuàng)建一個新任務(wù),并且該應用的“主”Activity 將作為堆棧中的根 Activity 打開。
當前 Activity 啟動另一個 Activity 時,該新 Activity 會被推送到堆棧頂部,成為焦點所在。 前一個 Activity 仍保留在堆棧中,但是處于停止狀態(tài)。?這個保存Activity的堆棧就是返回棧。了解了任務(wù)以及返回棧以后,我們就可以來正式學習啟動模式了。

standard

standard是系統(tǒng)默認的啟動模式,系統(tǒng)在啟動 Activity 的任務(wù)中創(chuàng)建 Activity 的新實例并向其傳送 Intent。Activity 可以多次實例化,而每個實例均可屬于不同的任務(wù),并且一個任務(wù)可以擁有多個實例。返回棧以“后進先出”對象結(jié)構(gòu)運行,下圖就是standard模式下返回棧的工作過程。


這里寫圖片描述

圖 1. 顯示任務(wù)中的每個新 Activity 如何向返回棧添加項目。 用戶按“返回”按鈕時,當前 Activity 隨即被銷毀,而前一個 Activity 恢復執(zhí)行。
在沒有特殊要求的大多數(shù)情況下,我們均使用這種默認的啟動模式。

singleTop

如果當前任務(wù)的頂部已存在 Activity 的一個實例,則系統(tǒng)會通過調(diào)用該實例的 onNewIntent() 方法向其傳送 Intent,而不是創(chuàng)建 Activity 的新實例(官方文檔的描述)。這句話的意思就是當一個Activity處于棧頂且啟動模式被設(shè)置為singleTop時,當再次啟動activity就會通過onNewIntent()來啟動它,在棧頂不會創(chuàng)建新的實例。
例如在默認情況下返回棧中依次有A-B-C-D四個activity,如果D的啟動模式為Standard,當再次啟動D時,任務(wù)棧中就會變?yōu)锳-B-C-D-D。但是如果D的啟動模式為singleTop,則當再次啟動D時,返回棧還是A-B-C-D。如果B的啟動模式為singleTop,當再次啟動B時,仍然會重新創(chuàng)建B的實例,返回棧變?yōu)锳-B-C-D-B.


這里寫圖片描述

這里ABCD的啟動模式均為standard,所以當D再次啟動D時會重新創(chuàng)建D的實例,回退時的順序為D-D-C-B-A.


這里寫圖片描述

這里將D的啟動模式設(shè)置為singletop,所以當D再次啟動D時由于此時位于棧頂?shù)木褪荄所以不會產(chǎn)生D的實例了,回退時的順序就是D-C-B-A
這里寫圖片描述

這里將B設(shè)置為了singletop,其他均為standard,點擊D時啟動了B,由于B并不在棧頂,所以重新創(chuàng)建了B實例,回退時的順序就是B-D-C-B-A.

singleTask

這是四大啟動模式中最難理解的一中了,系統(tǒng)創(chuàng)建新任務(wù)并實例化位于新任務(wù)底部的 Activity。但是,如果該 Activity 的一個實例已存在于一個單獨的任務(wù)中,則系統(tǒng)會通過調(diào)用現(xiàn)有實例的 onNewIntent() 方法向其傳送 Intent,而不是創(chuàng)建新實例。(這是官方文檔上的描述,我覺得描述的太抽象很難理解)。
要想徹底理解singleTask這個啟動模式,需要先理解一個taskAffinity。每個Activity都有taskAffinity屬性,這個屬性指出了它希望進入的Task(任務(wù))。如果一個Activity沒有顯式的指明該 Activity的taskAffinity,那么它的這個屬性就等于Application指明的taskAffinity,如果 Application也沒有指明,那么該taskAffinity的值就等于包名。而Task也有自己的affinity屬性,它的值等于它的根 Activity的taskAffinity的值。
現(xiàn)在就可以來解釋一下singleTask這個啟動模式了。當一個activity的啟動模式為singleTask,當要啟動這個activity時,首先會尋找有沒有和它taskAffinity相同的任務(wù),如果沒有,就會單獨創(chuàng)建一個以這個activity的taskAffinity為taskAffinity的任務(wù)棧,activity進入到這個新創(chuàng)建的任務(wù)棧中;如果有這個任務(wù)棧,還會繼續(xù)尋找在這個任務(wù)棧中有沒有它的實例存在,如不存在,此activity放入棧頂,如存在,則將此activity上面的所有activity彈出棧外,activity位于此返回棧的棧頂,在此過程中并未創(chuàng)建新的activity實例。
例如,有一個taskAffinity為1的task中存在A-B-C-D四個activity實例,當有B的taskAffinity為1且啟動模式為singleTask,此時啟動B時并不會啟動新的實例,taskAffinity為1的task會變?yōu)锳-B。如一個Activit E的taskAffinity為2且啟動模式為singleTask,則會產(chǎn)生一個新的taskAffinity為2的task,它的棧內(nèi)只有一個E,而taskAffinity為1的task中亦然是A-B-C-D。


這里寫圖片描述

這里將B的啟動模式設(shè)置為了singletask且taskAffinity未重新設(shè)置,當D啟動B時,由于之前A-B-C-D這個返回棧中已經(jīng)存在了B,所以B不會創(chuàng)建新的實例而是將C、D擠出返回棧,B通過onNewIntent()至于棧頂,所以回退時的順序就是B-A.

singleInstance

這種啟動模式也比較好理解,當一個activity以這個啟動模式啟動時,都會為它單獨創(chuàng)建一個任務(wù)棧,且這個任務(wù)棧中有且只能有一個它。

NOTE

無論 Activity 是在新任務(wù)中啟動,還是在與啟動 Activity 相同的任務(wù)中啟動,用戶按“返回”按鈕始終會轉(zhuǎn)到前一個 Activity。 但是,如果啟動指定 singleTask 啟動模式的 Activity,則當某后臺任務(wù)中存在該 Activity 的實例時,整個任務(wù)都會轉(zhuǎn)移到前臺。此時,返回棧包括上移到堆棧頂部的任務(wù)中的所有 Activity。 下圖顯示了這種情況。


這里寫圖片描述

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


這里寫圖片描述

如圖,首先打開了bootmode1,點擊了AA,假設(shè)產(chǎn)生了一個taskAffinity為bootmode1返回棧,其結(jié)構(gòu)是AA-BB,點擊home鍵將其放入后臺后打開BootMode,依次點擊A-B-C-D,其中D按鈕的點擊效果是使用隱式啟動打開bootmode1里的BB,然后一直按返回鍵,我們可以看到返回的順序為BB-AA-D-C-B-A,符合上面的結(jié)論.

intent的標記

FLAG_ACTIVITY_NEW_TASK
在新任務(wù)中啟動 Activity。如果已為正在啟動的 Activity 運行任務(wù),則該任務(wù)會轉(zhuǎn)到前臺并恢復其最后狀態(tài),同時 Activity 會在 onNewIntent() 中收到新 Intent。這種啟動標記的作用相當于啟動模式中的singleTask。
FLAG_ACTIVITY_SINGLE_TOP
如果正在啟動的 Activity 是當前 Activity(位于返回棧的頂部),則 現(xiàn)有實例會接收對 onNewIntent() 的調(diào)用,而不是創(chuàng)建 Activity 的新實例。這種啟動標記的作用相當于啟動模式中的singleTop。
FLAG_ACTIVITY_CLEAR_TOP
如果正在啟動的 Activity 已在當前任務(wù)中運行,則會銷毀當前任務(wù)頂部的所有 Activity,并通過 onNewIntent() 將此 Intent 傳遞給 Activity 已恢復的實例(現(xiàn)在位于頂部),而不是啟動該 Activity 的新實例。而這個標記通常與FLAG_ACTIVITY_NEW_TASK在一起結(jié)合使用。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容