Android activity 启动模式 详解

在Android 中最常用到的组件就是activity .
Activity 有4种启动模式
standard               默认的启动模式,每次都启动一个新的Activity
singleTop              当站定的Activity与要启动的Activity 是同一个时, 则不启动新的Activity
singleTask             把启动的Activity的Activity不在栈顶, 那么会把栈顶的Activity砍掉, 走onNewIntent方法
singleInstance       只存在一个实例,且在单独的栈中

ok  上面头提到栈, 对 Android的没一个app 都由一个知己的Activity 栈
ok 下面一个一个来看看 这4种启动模式到底有什么不同

1. standard
这个是默认的启动模式  ,每次都会启动新的Activity,  很好验证的就不多说了

2. singleTop

有 ActivityA,ActivityB,ActivityC,ActivityD
ActivityA 是 mainActivity
ActivityC,ActivityD 是 singleTop
ActivityA,ActivityB 是 standard

1. A -> B 正常
2. A -> B -> C 正常启动C
3. A -> B -> C ->C ,  这里没有重新创建C, 没有走C 的onCreate方法 而是走了onNewIntent 方法, 这就是 singleTop 的特性
4. A -> B -> C -> D, 这里正常启动D
5. A -> B -> C -> D -> D, 和上面 C -> C 一样, 也没有再次出那个键D 走了 onNewIntent 方法
6. A -> B -> C -> D -> C, 这里正常重选创建了C
7. A -> B -> C -> D -> C -> D, 这里正常重选创建了D
ok 生面的例子 可以知道  singleTop 启动模式 , 就是如果要启动的这个Activity 已经在栈顶了, 那么就不会去启动新的Activity,会走 onNewIntent 方法
如果她 不在栈顶, 那么就会启动一个新的Activity 会走 onCreate方法

ok 下面看看  singleTask

3. singleTask
ActivityA 是 mainActivity
ActivityC,ActivityD 是 singleTask
ActivityA,ActivityB 是 singleTask

1. A -> B 正常
2. A -> B -> C 正常启动C
3. A -> B -> C ->C ,  这里没有重新创建C, 没有走C 的onCreate方法 而是走了onNewIntent 方法, 这就是 singleTop 的Text
4. A -> B -> C -> D, 这里正常启动D
5. A -> B -> C -> D -> D, 和上面 C -> C 一样, 也没有再次出那个键D 走了 onNewIntent 方法
6. A -> B -> C -> D -> C, 这里没有重新创建C, 没有走C 的onCreate方法 而是走了onNewIntent 方法, 但是 D 被移除栈了
变成了 : A -> B -> C
7. A -> B -> C -> D, 这里正常启动D
8. A -> B -> C -> D -> C, 和上面一个 没有没有重新创建C, 同样D 被移除栈了
ok  经过上面的测试 可以得出结论:
如果要启动的这个Activity 已经在栈顶了, 那么就不会去启动新的Activity,会走 onNewIntent 方法
如果要启动的这个Activity 不在栈中, 那就会正常的创建一个 Activity 在栈顶
如果要启动的这个Activity 在栈中, 但是不在栈顶, 上面还有几个Activity 如果 Activity1, Activity2, 那么系统会把 Activity1, Activity2 移除栈, 然后 走 Activity 的onNewIntent 方法

但是在google的官方文档中 是有提到说, 使用 singleTask 启动Activity 会新开一个栈的,但是在上面的测试的一系列过程中, 通过答疑TaksId 看到的结果是没有新开栈的.

这是为什么的,  这里就要要引入一个新的概念  taskAffinity 亲和力,
默认的 在一个app中所有的Activity的  taskAffinity 都是一个样的 都是该app 的包名

在上面的测试中 如果 吧 ActivityD的  taskAffinity 改成与包名不同的话, 那么
9. A -> B -> C -> D, 这里正常启动D 但是是在一个新的战中的启动的, D的task Id 与 ABC 不用如下Log:
11-04 22:41:31.409 23514-23514/com.zuimeia.activitymodel D/Activity: ActivityA onCreate taskId = 881
11-04 22:41:33.417 23514-23514/com.zuimeia.activitymodel D/Activity: ActivityB onCreate taskId = 881
11-04 22:41:34.663 23514-23514/com.zuimeia.activitymodel D/Activity: ActivityC onCreate taskId = 881
11-04 22:41:35.949 23514-23514/com.zuimeia.activitymodel D/Activity: ActivityD onCreate taskId = 882

10. A -> B -> C -> D -> C 这里没有重新创建C,走了onNewIntent 方法 但是 D没有被移除掉,
     因为 D 与 ABC 不在同一个栈中, 那么  C 在它所在的栈是栈顶 所有没有移除其他Activity

11. A -> B -> C -> D -> B  这里会重新创建B 但是B 与D 是在同一个栈中
12. A -> B -> C -> D -> B -> A  这里会重新创建A 创建的A 与 B 与D 是在同一个栈中

13. A -> B -> C -> D -> C ->B 这里会重新创建B 这里的B 与前面的ABC 在同一个栈中

ok 下面来看看 singleInstance

4.singleInstance
ActivityA 是 mainActivity
ActivityC 是 singleTask
ActivityA,ActivityB , ActivityD是 singleTask

1. A -> B 正常
2. A -> B -> C 正常启动C, C在一个单独的栈中
3. A -> B -> C -> D正常启动D, D 与AB 在一个栈中 
但是在
D 按返回的时候  回到的是B,
B 按返回的时候  回到的是A
A 按返回的时候  回到的是C

4. A -> B -> C -> D -> C 这里没有重新创建C 走了C 的onNewIntent 方法
返回的路线是: C -> D -> B -> A

ok 可以得到singleInstance的结论

1. 如果启动的Activity是 singleInstance 那么他会被放到另外一个栈中去,
2. singleInstance 的这个 Activity 所启动的这个Activity 与它不在同一个栈中, 即上面的步骤3  D 与AB 在一个栈中 
3. 如果要启动的这个singleInstance 的Activity已经启动了, 那么就不会重新创建了 会走 onNewIntent 方法 上面步骤4


你可能感兴趣的:(android,singletask,启动模式)