Android開發藝術2之Activity的啓動模式

任務棧Task ,是一種用來放置Activity實例的容器,具有2個基本操作:壓棧和彈出。我們啓動一個Application的時候,系統會爲它默認創建一個對新的Task,用來盛放根Activity,默認啓動Activity會放在同一個Task中,新啓動的Activity會被壓入啓動它的那個Activity的棧中,按下Home鍵回到桌面,再啓動另一個應用,這時候之前那個Task就被移到後臺,成爲後臺任務棧,而剛啓動的那個Task就被調到前臺,成爲前臺任務棧,Android系統顯示的就是前臺任務棧中的Top實例Activity,當然,同一個應用可以有多個任務棧,但是肯定只存在一個任務棧在前臺。下面提一下他的一個重要的屬性taskaffinity,也就是所謂的親和力。這個屬性不光Task有,Activity也有(affinity),他們就是通過這個屬性值來進行關聯的,不然你想想,一個應用有這麼多Activity,並且可以有多個task,那麼讓activity實例隨便入哪個棧都行,那豈不是亂成一團了。

affinity系統默認會給他一個值,那就是應用的包名。並且如果自己重新給他值的話就在xml文件中定義,但是他的定義必須包含".",也就是像包名一樣中間要有點號。

以上簡單的介紹了任務棧,下面我們正式講下我們的Activity的啓動模式和標誌位,首先分爲四種啓動模式,分別爲:標準模式,棧頂複用模式,棧內複用模式,單例模式。

1.standard 即標準模式,他是系統默認的啓動方式,這個任務棧中可以有多個相同的Activity實例,多個相同Activity實例也可以分佈在不同的任務棧中,這時候是誰啓動他,他就和誰在一個任務棧中,這時候我們要聯繫到我們遇到過的一個異常:android.util.AndroidRuntimeException:....,具體內容大家試試這樣啓動一個Activity就會出來,使用ApplicationContext啓動一個standard模式的Activity。我們分析下,其實這個錯誤的出現就是因爲默認模式下,被誰啓動,activity就翻到那個任務棧中去,而全局的上下文對象是沒有任務棧存在的,所以就會報錯了,解決這個問題可以更改啓動的上下文爲某個activity對象,當然我們如果將被啓動的activity設置他的標誌位爲FLAG_ACTIVITY_NEW_TASK 也同樣可以,這時候就相當於把Activity改爲了singleTask模式啓動了。

2.singleTop 即棧頂唯一模式,這種模式下,如果Activity位於任務棧的棧頂,那麼此Activity不會被重新創建,也就是說 不會調用 生命週期中的 onCreate和onStart 方法,但是 會回調 另一個方法 onNewIntent ,這時候我們可以在這個回調方法里根據參數Intent intent進行自己的相關處理。如果新啓動的Activity實例不存在,或者存在但是不是位於棧頂,那麼和正常一樣的創建它。

3.singleTask 即棧內唯一,這個其實是一種單例模式,只要這個任務棧中存在這個Activity的實例,那麼就不再創建它,而是直接複用其實例,這時候也會回調onNewIntent,這時候有個問題,這個實例如果不是在棧頂,那麼它要到棧頂來,唯一途徑就是把它之前的實例全部彈出,實際上就是說singleTask具有clearTop的效果。當然這是簡單的說明,下面幾個例子讓你更能理解:

例1.目前有S1任務棧中有ABC,這個時候要啓動Activity D並且D是singleTask模式,其所需的任務棧爲S2(之所以不是S1因爲爲他指定了affinity屬性),這時候由於S2和D都不存在,所以會先創建任務棧S2,然後在創建實例D壓入棧底。

例2.情況和1相同,只是D所需任務棧同樣是S1,這時候就只要創建D的實例並將其壓入到棧S1中即可。

例3.如果D所需的任務棧爲S1,並且當前S1中的情況爲ADBC,這時候D的實例存在了,那麼會將BC出棧,剩下AD,這就是singleTask默認具有clearTop的效果

4.singleInstance 單例模式,這是一種加強型的singleTask,他具有singleTask的所有特性,並且擁有一個獨特的地方就是,他會單獨佔用一個任務棧,比如Activity A是singleInstance模式,那麼啓動他的時候,系統會爲他單獨創建一個任務棧將其壓入,如果再次啓動他,他已經存在了,那麼就直接複用該任務棧。

以上就是關於啓動模式的說明,注意一點就是TaskAffinity這個屬性主要是與singleTask或者allowTaskReparenting屬性配對使用,在其他情況下是沒有意義的。

下面講下關於標誌位,Activity的標誌位Flags有很多種,其效果也有很多,比如可以用來設定啓動模式,可以用來影響運行狀態,下面介紹幾個常用的標誌位:

FLAG_ACTIVITY_NEW_TASK

該標誌位作用於指定Activity的singleTask啓動模式一樣。

FLAGE_ACTIVITY_SINGLE_TOP

該標誌位的作用和指定Activity的singleTop效果一致。

FLAGE_ACTIVITY_CLEAR_TOP

此標記位的效果就有意思了,擁有它的Activity會將與他在同一個任務棧中之前Activity都出棧,這個標誌通常和singleTask配合使用時,如果實例存在,就調用他的onNewIntent,並將他之上的其他實例都清除,但是如果擁有該標誌位的Activity是默認啓動模式standard,那麼他會連同自己一起清除,然後再重新創建實例,這點要注意好,所以之前我們說了singleTask默認具有此標誌的效果

以上就是簡單的說了一下啓動模式和標誌位。爲Activity設置啓動模式我們有2中方式:

1.在XML文件中定義 android:launchMode="singleTask"

2.在啓動意圖的時候設置:intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

這倆種方式存在一些區別:

優先級第二種大於第一種,當倆種方式同時存在的時候以第二種方式爲準,第一種方式爲輔。倆種方式也存在適用範圍的區別,第一種方式無法直接爲Activity設定FLAG_ACTIVITY_CLEAR_TOP標誌的效果,而第二種方式無法直接設置出singleInstance模式的效果。

希望看我能讓你在開發中對啓動模式和flags標誌位進行靈活使用~~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章