一:前言
四種模式分別為standard, singleTop, singleTask, singleInstance。自己應該明確一個概念先,single到底要single什麼。每一個應用app都有一個包名,然後每一個應用都會有一個task,這個task和包名對應起來,如果要建立一個新task,名字就得不一樣。
- 一個應用會有一個包名,應用中預設有一個以包名為名字的task
- task是一個概念,實現是stack棧。
- task用來管理activity,一個activity轉到另一個activity,就會把新activity壓棧,遵循先進後出。
- task中的activity可以跨應用,比如說app中跳轉到微信,然後按返回鍵又可以回到自己那個應用。
二:如何改變啟動模式
- 在manifest中對activity設定
- 更改Intent啟動activity時的flag
三:直接從singleTop開始
三個activity,activity1可以跳轉到activity2,activity2可以跳轉到activity3.
1:第一種情況,棧頂已有例項
棧底---------------------------------------》棧頂 acitivity1 activity2 acitivity3 這時候以singleTop模式啟動activity3,重用舊例項, 備註:順便呼叫activity3的onNewIntent()方法 棧底---------------------------------------》棧頂 acitivity1 activity2 acitivity3
2:第二種情況,棧頂沒有例項
棧底---------------------------------------》棧頂 acitivity1 acitivity3 activity2 這時候以singleTop模式啟動activity3,建立新例項 棧底---------------------------------------》棧頂 acitivity1 acitivity3 activity2 activity3(new)
四:很簡單的singleTask
注意要在manifest中設定
android:launchMode="singleTask"
(我發現設不設定intent的flag都沒用,關鍵是設定這個,只設定flag沒有用)
1:第一種情況,在manifest中沒有設定了taskAffinity
當前task沒有這個activity的例項就建立一個,放在棧頂;若是有例項,就把那個例項上面的activity全部出棧(銷燬),並呼叫要啟動的activity例項的:onRestart, onStart, onResume
棧底---------------------------------------》棧頂 acitivity1 acitivity3 activity2 這時候以singleTast模式啟動activity3,但沒有taskAffinit 會把已有的activity3上面的activity,即activity2出棧,銷燬 並呼叫已有的activity3的onRestart,onStart, onResume 棧底---------------------------------------》棧頂 acitivity1 acitivity3 (old)
即singleTask確保在當前task例項唯一
2:第二種情況,在manifest中設定了taskAffinity
2.1:這個task已被建立
棧底---------------------------------------》棧頂
task1:
acitivity1 acitivity3 activity2
task2:
acitivity1 acitivity3 activity2
以singleTask模式啟動activity3,指定task2,表現和第一種情況一樣
把上面的activity都出棧
task1:
acitivity1 acitivity3 activity2
task2:
acitivity1 acitivity3(old)
2.2:這個task未被建立
棧底---------------------------------------》棧頂 task1: acitivity1 acitivity3 activity2 以singleTask模式啟動activity3,指定task2 會建立task2,並建立新例項放進去 task1: acitivity1 acitivity3 activity2 task2: activity3(new)
ps:之後activity3啟動的其他activity,除非新指定task,否則都在activity3所在的棧中了,即所謂嫁雞隨雞嫁狗隨狗
singleTask名字誤導很大,我覺得名字為singleAtTask更貼切。
五:更簡單的singleInstance
啟動模式為singleInstance的activity,在整個手機中,只能有一個例項,再次呼叫的時候,會找到這個例項並把它調到前臺。
比如說activity1已singleInstance模式啟動,那就把它調到前臺(已存在的話)。
- activity1屬於一個唯一的task,這個task只有它一個
- activity1啟動其他activity,若這個activity指明taskAffinit(即使不是singleTask模式),就在指明的task中建立,若沒有指明taskAffinit,就預設找應用包名的task。這邊邏輯和singleTask很像了。
參考資料:https://blog.csdn.net/zhangjg_blog/article/details/10923643
https://www.kancloud.cn/alex_wsc/android_art/1828110