启动模式简介:
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,不会将任何活动出栈