當我們在 Android 應(yīng)用程序中,添加 launchMode 屬性址愿,一起來看看會發(fā)生什么吧该镣。
<activity
android:name=".MainActivity"
android:launchMode="singleTop">
</activity>
假設(shè)現(xiàn)在有 A,B响谓,C损合,D,E娘纷,F 個 Activity嫁审。
-
launchMode="singleTop"
給 D 添加 launchMode="singleTop"
例子 1:
之前的 Activity 任務(wù)棧狀態(tài)
D-(D 位于任務(wù)棧的頂端)
C
B
A
從任何服務(wù)或其他應(yīng)用程序或從某處啟動 D
最終的 Activity 任務(wù)棧狀態(tài)
D
C
B
A
例子 2:
之前的 Activity 任務(wù)棧狀態(tài)
C
B
A
從任何服務(wù)或其他應(yīng)用程序或從某處啟動 D
最終的 Activity 任務(wù)棧狀態(tài)
D
C
B
A
例子 3:
之前的 Activity 任務(wù)棧狀態(tài)
C
D
B
A
在 AndroidStudio 中的 Terminal 窗口輸入以下命令,查看當前任務(wù)棧的狀態(tài)失驶。
-
adb shell dumpsys activity xxx(當前應(yīng)用程序的包名)
TASK com.example.wyj.activitydemo id=28815 ACTIVITY com.example.wyj.activitydemo/.CActivity ... ACTIVITY com.example.wyj.activitydemo/.DActivity ... ACTIVITY com.example.wyj.activitydemo/.BActivity ... ACTIVITY com.example.wyj.activitydemo/.AActivity
從 C 開啟 D
最終的 Activity 任務(wù)棧狀態(tài)
D-(之前的 D 沒有位于棧頂土居,創(chuàng)建新的實例放置棧頂)
C
D
B
A
再次輸入 adb 命令來驗證當前任務(wù)棧的狀態(tài)。
TASK com.example.wyj.activitydemo id=28815 ACTIVITY com.example.wyj.activitydemo/.DActivity ... ACTIVITY com.example.wyj.activitydemo/.CActivity ... ACTIVITY com.example.wyj.activitydemo/.DActivity ... ACTIVITY com.example.wyj.activitydemo/.BActivity ... ACTIVITY com.example.wyj.activitydemo/.AActivity
-
launchMode="singleTask"
給 C 添加 launchMode="singleTask"
例子 1:
之前的 Activity 任務(wù)棧狀態(tài)
D
C
B
A
任務(wù)棧狀態(tài):
TASK com.example.wyj.activitydemo id=28819 ACTIVITY com.example.wyj.activitydemo/.DActivity ... ACTIVITY com.example.wyj.activitydemo/.CActivity ... ACTIVITY com.example.wyj.activitydemo/.BActivity ... ACTIVITY com.example.wyj.activitydemo/.AActivity
啟動 C
最終的 Activity 任務(wù)棧狀態(tài)
C
B
A
任務(wù)棧狀態(tài):
TASK com.example.wyj.activitydemo id=28819 ACTIVITY com.example.wyj.activitydemo/.CActivity ... ACTIVITY com.example.wyj.activitydemo/.BActivity ... ACTIVITY com.example.wyj.activitydemo/.AActivity
注: D 被銷毀
例子 2:
之前的 Activity 任務(wù)棧狀態(tài)
B
A
啟動 C
最終的 Activity 任務(wù)棧狀態(tài)
C
B
A
-
launchMode="singleInstance"
給 E 添加 launchMode="singleInstance"
例子1:
D
C
B
A
啟動 E
最終的 Activity 任務(wù)棧狀態(tài)
E
D
C
B
A
任務(wù)棧狀態(tài):
TASK com.example.wyj.activitytest id=29880 ACTIVITY com.example.wyj.activitytest/.DActivity ... ACTIVITY com.example.wyj.activitytest/.CActivity ... ACTIVITY com.example.wyj.activitytest/.BActivity ... ACTIVITY com.example.wyj.activitytest/.AActivity ... TASK com.example.wyj.activitytest id=29881 ACTIVITY com.example.wyj.activitytest/.EActivity
注: A嬉探,B擦耀,C,D 位于一個 任務(wù)棧涩堤,E 位于新的任務(wù)棧眷蜓。
例子2:
在例子1的基礎(chǔ)上,從 E 打開 F
最終的 Activity 任務(wù)棧狀態(tài)
F
D
C
B
A
E
任務(wù)棧狀態(tài):
TASK com.example.wyj.activitytest id=29887 ACTIVITY com.example.wyj.activitytest/.EActivity ... TASK com.example.wyj.activitytest id=29886 ACTIVITY com.example.wyj.activitytest/.FActivity ... ACTIVITY com.example.wyj.activitytest/.DActivity ... ACTIVITY com.example.wyj.activitytest/.CActivity ... ACTIVITY com.example.wyj.activitytest/.BActivity ... ACTIVITY com.example.wyj.activitytest/.AActivity
注: A胎围,B吁系,C,D白魂, F 位于一個 任務(wù)棧汽纤,E 位于新的任務(wù)棧。
例子3:
之前的任務(wù)棧狀態(tài)
A
B
E
從 A 打開 E
最終的任務(wù)棧狀態(tài)
E
A
B
任務(wù)棧狀態(tài):
TASK com.example.wyj.activitytest id=29889 ACTIVITY com.example.wyj.activitytest/.AActivity ... ACTIVITY com.example.wyj.activitytest/.BActivity ... TASK com.example.wyj.activitytest id=29890 ACTIVITY com.example.wyj.activitytest/.EActivity
-
launchMode="standard"
給 B 添加 launchMode="standard"
之前的任務(wù)棧狀態(tài)
D
C
B
A
開啟 B
最終的任務(wù)棧狀態(tài)
B- 新的實例
D
C
B
A
現(xiàn)在讓我們通過在 Intent 設(shè)置標記位來為 Activity 指定啟動模式
-
FLAG_ACTIVITY_NEW_TASK
從 D 打開 E福荸,并添加這個標記位
val intent = Intent(this@DActivity, BActivity::class.java) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) startActivity(intent)
例子 1:
之前的 Activity 任務(wù)棧狀態(tài)
D
C
B
A
最終的 Activity 任務(wù)棧狀態(tài)
E
D
C
B
A
注: A蕴坪,B,C敬锐,D 位于一個 任務(wù)棧背传,E 位于新的任務(wù)棧。
例子 2:
從 D 開啟 B台夺,并添加這個標記位
之前的 Activity 任務(wù)棧狀態(tài)
D
C
B
A
最終的 Activity 任務(wù)棧狀態(tài)
B
D
C
B
A
注: A径玖,B,C颤介,D 位于一個 任務(wù)棧梳星,打開的 B 位于新的任務(wù)棧赞赖,
其效果和在 xml 中為 Activity 指定 singleTask 啟動模式相同。
-
FLAG_ACTIVITY_CLEAR_TASK
例子 1:
從 D 開啟 E丰泊,并添加這個標記位
之前的 Activity 任務(wù)棧狀態(tài)
D
C
B
A
最終的任務(wù)棧狀態(tài)
E
注: 其它的 Activity 都被銷毀薯定。
例子 2:
從 D 開啟 B,并添加這個標記位
之前的 Activity 任務(wù)棧狀態(tài)
D
C
B
A
最終的 Activity 任務(wù)棧狀態(tài)
B
注: 新的實例 B 被創(chuàng)建瞳购,其它的 Activity 被銷毀话侄。
-
FLAG_ACTIVITY_SINGLE_TOP
其效果和在 xml 中為 Activity 指定 singleTop 啟動模式相同。
-
FLAG_ACTIVITY_CLEAR_TOP
從 D 開啟 B学赛,并添加這個標記位
之前的 Activity 狀態(tài)
D
C
B
A
最終的 Activity 狀態(tài)
B- 舊的實例 B
A
注: 位于 B 上面的 Activity 被銷毀年堆,
singleTask 啟動模式和該標記位效果相同。
結(jié)語
-
通過兩種方式都可以為 Activity 設(shè)置啟動模式盏浇,但還是有區(qū)別的
-
優(yōu)先級
- 在代碼中添加標記位的優(yōu)先級高于 xml
-
限定范圍
- 在 xml 中無法直接為 Activity 設(shè)定 FLAG_CLEAR_TOP 標識
- 在代碼中無法為 Activity 指定 singleInstance 模式
-
參考資料
- 原文鏈接
- Android 開發(fā)藝術(shù)探索