Android的4種啓動模式

啓動模式簡介:

1. standard:

每次啓動都會創建一個新的實例,一個任務棧可以有多個實例,每個實例也可以屬於不同的任務棧

2. singleTop:

棧頂複用。如果活動在棧頂,再次想創建該活動,不會創建新的Activity,同時會回調onNewIntent,通過該函數可以獲得請求的信息

3. singleTask:

棧內複用,這是一種單例模式。只要Activity在一個棧中存在,多次調用都不會重新創建實例,也會回調onNewIntent,分5種情況

a) 目前任務棧S1中有ABC,這個時候Activity  D以singleTask模式請求啓動,其所需要的任務棧爲S2,由於S2和D的實例都不存在,所以先創建任務棧S2,然後再創建D的實例並將其入棧到S2,S1此時爲ABC,S2爲D

b) 目前任務棧S1中有ABC,D以singleTask模式請求啓動,其所需要的任務棧爲S1,由於S1已經存在,所以直接創建D的實例並將其入棧到S1,S1此時爲ABCD

c) 目前任務棧S1中有ADBC,D以singleTask模式請求啓動,其所需要的任務棧爲S1,根據複用原則B和C出棧,D位於棧頂,此時S1爲AD

4. singleInstance:

單實例模式。全局單例,當以singleInstance模式創建一個Activity時,會單獨創建一個任務棧,然後在該任務棧中創建該Activity,該任務棧只能存在一個Activity

例子:

3個Activity,分別爲A、B、C

1.  A爲standard,B、C爲singleInstance

同時設置B、C的任務棧爲com.example.sun.task1,A在默認任務棧

設默認任務棧爲S1,設com.example.sun.task爲S2

[java] view plain copy
  1. <activity android:name=".A">  
  2.     <intent-filter>  
  3.         <action android:name="android.intent.action.MAIN" />  
  4.   
  5.         <category android:name="android.intent.category.LAUNCHER" />  
  6.     </intent-filter>  
  7. </activity>  
  8. <activity android:name=".B"  
  9.     android:taskAffinity="com.example.sun.task1"  
  10.     android:launchMode="singleTask"/>  
  11. <activity android:name=".C"  
  12.     android:taskAffinity="com.example.sun.task1"  
  13.     android:launchMode="singleTask"/>  

啓動順序:A → B → C → A → B

退出順序:B → A → 桌面(按兩次返回鍵)

a)  A → B → C:

啓動A:A的taskAffinity繼承自包名,創建默認任務棧(即S1),然後將在S1中創建A,S1爲前臺任務棧

啓動B:根據singleTask的啓動原則a點,因爲沒有任務棧S2,創建任務棧S2,然後創建B,

             此時有兩個任務棧S1,S2。因爲此時運行B,S2爲前臺任務棧。

啓動C:根據singleTask的啓動原則b點,因爲存在任務棧S2,直接創建任務棧S2,然後創建 C,

             此時有兩個任務棧S1,S2。因爲此時運行C,S2爲前臺任務棧。如下圖所示


在terminal輸入adb shell dumpsys activity,找到Running activities

可以看到C,B在com.example.sun.task1(即S2)中,A在com.example.sun.webtest(即S1)中,其他不用管

b)  A → B → C → A:

再啓動A,因爲是C啓動A,並且A爲standard,會把A創建在C的任務棧中,並位於棧頂


c)  A → B → C → A → B:

從A中啓動B,因爲B爲singleTask,不會創建新的實例,根據singleTask的原則c點,把A、C出棧


 

d) 退出順序:B → A → 桌面

此時再按返回,B從S2中出棧,S2任務棧不存在了,此時只能切換到後臺任務棧S1,顯示A,

再次按返回鍵,A從從S1中出棧,就回到了桌面

2.  A、B、C爲singleInstance

同時設置A的任務棧爲com.example.sun.task1,BC的任務棧爲com.example.sun.task2

設com.example.sun.task1任務棧爲S1,com.example.sun.task2任務棧爲S2

[java] view plain copy
  1. <activity android:name=".A"  
  2.     android:taskAffinity="com.example.sun.task1"  
  3.     android:launchMode="singleTask">  
  4.     <intent-filter>  
  5.         <action android:name="android.intent.action.MAIN" />  
  6.   
  7.         <category android:name="android.intent.category.LAUNCHER" />  
  8.     </intent-filter>  
  9. </activity>  
  10. <activity android:name=".B"  
  11.     android:taskAffinity="com.example.sun.task2"  
  12.     android:launchMode="singleTask"/>  
  13. <activity android:name=".C"  
  14.     android:taskAffinity="com.example.sun.task2"  
  15.     android:launchMode="singleTask"/>  

啓動順序:A → B → C → A → B

退出順序:B → A → 桌面(按兩次返回鍵)

這裏結果是和上面一樣的,但任務棧的內容不一樣,因爲A爲singleTask,具體分析如下:

a)  A → B → C:(基本和前面一樣)

啓動A:根據singleTask的啓動原則a點,因爲沒有任務棧S1,創建任務棧S1,然後將在S1中創建A,S1爲前臺任務棧,

啓動B:根據singleTask的啓動原則a點,因爲沒有任務棧S2,創建任務棧S2,然後創建B,

             此時有兩個任務棧S1,S2。因爲此時運行B,S2爲前臺任務棧。

啓動C:根據singleTask的啓動原則b點,因爲存在任務棧S2,直接創建任務棧S2,然後創建 C,

             此時有兩個任務棧S1,S2。因爲此時運行B,S2爲前臺任務棧,如下圖所示


b)  A → B → C → A:

再啓動A,因爲A爲singleTask,不會把A創建在C的任務棧中,而是切換S1爲前臺任務,S2變爲後臺任務

    

c)  A → B → C → A → B:

啓動B,因爲B爲singleTask,根據singleTask的原則c點,把C出棧,同時S1變爲後臺任務,S2變爲前臺任務



d) 退出順序:B → A → 桌面(按兩次返回鍵)

此時再按返回,B從S2中出棧,S2任務棧不存在了,此時只能切換到後臺任務棧S1,顯示A,

再次按返回鍵,A從從S1中出棧,就回到了桌面


如果例子2中,設置了A第一次啓動B,第二啓動C,即A → B → C → A → C,此時退出順序爲C → B → A,因爲從A啓動C 後,C在S2的棧頂,直接將前臺任務切換到S2,不會將任何活動出棧

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