啓動模式簡介:
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
- <activity android:name=".A">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- <activity android:name=".B"
- android:taskAffinity="com.example.sun.task1"
- android:launchMode="singleTask"/>
- <activity android:name=".C"
- android:taskAffinity="com.example.sun.task1"
- 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
- <activity android:name=".A"
- android:taskAffinity="com.example.sun.task1"
- android:launchMode="singleTask">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- <activity android:name=".B"
- android:taskAffinity="com.example.sun.task2"
- android:launchMode="singleTask"/>
- <activity android:name=".C"
- android:taskAffinity="com.example.sun.task2"
- 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,不會將任何活動出棧