【android】Activity的啓動模式

啓動模式的分類

Activity目前有四種啓動模式:standard、singleTop、singleTask、singleInstance。

standard

標準模式,這也是系統的默認模式。每次啓動一個Activity都會重新創建一個新的實例,不管這個實例是否已經存在。被創建的實例的生命週期符合典型情況下的Activity的生命週期,這是一種典型的多實例實現,有一個任務棧中可以有多個實例,每個實例也可以屬於不同的任務棧。在這種模式下,誰啓動了這個Activity,那麼這個Activity就運行在啓動它的那個Activity所在的棧中。

eg:Activity A啓動了Activity B (B是標準模式),那麼B就會進入到A所在的棧中。

PS:是誰啓動了Activity,啓動Activity的對象是否有任務棧,(比如用Context去啓動standard模式的Activity的時候會報錯的,因爲Context並沒有任務棧),如果沒有,那就需要爲待啓動的Activity指定 FLAG_ACTIVITY_NEW_TASK 標誌位,這樣啓動的時候就會爲它創建一個新的任務棧,這個時候,待啓動的Activity實際是以singleTask模式啓動的。


singleTop

棧頂複用模式,在這種模式下,如果新Activity已經位於任務棧的棧頂,那麼此Activity不會被重新創建,同時它的onNewIntent方法會被重新調用,通過此方法的參數我們可以取出當前請求信息。需要注意的是,這個Activity的onCreate()、onStart()不會被系統調用,因爲它並沒有發生改變。如果新Activity的實例已存在但不是位於棧頂,那麼新Activity依然會重新創建。

eg:假設目前棧內的情況爲 (棧底)ABCD(棧頂) ,這是假設要再次啓動D,如果D的啓動模式爲singleTop,那麼棧內的情況依然是ABCD;如果D的啓動模式是standard,那麼棧內情況爲ABCDD。


singleTask

棧內複用模式。這是一種單實例模式,在這種模式下,只要Activity在一個棧中存在,那麼多次啓動此Activity都不會創建實例,和singleTop一樣,系統也會回調其onNewIntent。具體一點,當具有singleTask模式的Activity請求啓動後,比如Activity A,系統首先會尋找在A想要的任務棧,如果不存在,就重新創建一個任務棧,然後創建A的實例後把A放在棧中。如果存在A所需要的任務棧,這時要看A是否在任務棧中有實例存在,如果有實例存在,那麼系統就會把A調到棧頂並調用它的onNewIntent方法,如果實例不存在,就創建A的實例並把A壓入棧中。

eg:目前任務棧S1中的情況爲ABC,這個時候Activity D以singleTask模式 請求啓動,其所需要的任務棧爲S2,由於S2和D的實例均不存在,所以系統會先創建任務棧S2,然後再創建D的實例並將其入棧到S2。

另外一種情況,假設D所需的任務棧爲S1,那麼S1已經存在,所以系統會直接創建D的實例並將其入棧到S1。

如果D所需的任務棧爲S1,並且當前任務棧S1的情況爲ADBC,根據棧內複用原則,此時D不會重新創建,系統會D切換到棧頂並調用其onNewIntent方法,同時由於singleTask默認具有clearTop的效果,會導致棧內所有在D上面的Activity全部出棧,於是最終S1中的情況爲AD。所以:在所需任務棧中有待啓動Activity的實例的情況下,singleTask模式的Activity啓動時並不是重新回到任務棧的棧頂,而是將該Activity以上的其他Activity全部清除。


singleInstance

單實例模式,這是一種加強的singleTask模式,它除了具有singleTask模式的所有特性外,還加強了一點,那幾十具有此模式的Activity只能單獨的位於一個任務棧中。

eg:Activity A是singleInstance模式,當A啓動後,系統會爲它創建一個新的任務棧,然後A獨自在這個新的任務棧中,由於棧內複用特性,後續的請求均不會創建新的Activity,除非這個獨特的任務棧被系統銷燬了。


如何指定啓動模式

1、通過AndroidMenifest

<activity
    android:name="com.***.***"
    android:configChanges="screenLayout"
    android:launchMode="singleTask"
    android:label="@string/app_name"/>

2、通過在Intent中設置標誌位

Intent intent = new Intent();
intent.setClass(MainActivity.this,SecondActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

這兩種方式都可以爲Activity指定啓動模式,但是兩者還是有區別的。首先,優先級上,第二種方式的優先級要高於第一種,當兩種方式同時存在時,以第二種方式爲準;其次,上述兩種方式在限定方式上有所不同,第一種方式無法直接爲Activity設定 FLAG_ACTIVITY_CLEAR_TOP 標識,而第二種方式無法爲Activity指定singleInstance模式。


Activity的Flags

Flags 等同於 說明
FLAG_ACTIVITY_NEW_TASK singleTask
FLAG_ACTIVITY_SINGLE_TOP singleTop
FLAG_ACTIVITY_CLEAR_TOP clearTop 具有此標誌位的Activity,當它啓動時,在同一個任務棧中所有位於它上面的Activity都要出棧
FLAG_ACTIVITY_EXECLUDE_FROM_RECENTS android:execludeFromRecents=”true”(XML中) 當某些情況下我們不希望用戶通過歷史列表回到我們的Activity的時候這個標記比較有用
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章