1.Standard(标准模式-默认)
例:我们从StandardActivity跳转到A_Activity,再次跳转到B_Activity,再次跳转到StandardActivity,再次跳转到A_Activity
打印的log
I/BaseActivity: *****************start*********************
I/BaseActivity: onCreate
I/BaseActivity: class name ... StandardActivity
I/BaseActivity: task id ... 55
I/BaseActivity: hashCode ... 159258267
I/BaseActivity: *****************end*********************
I/BaseActivity: *****************start*********************
I/BaseActivity: onCreate
I/BaseActivity: class name ... A_Activity
I/BaseActivity: task id ... 55
I/BaseActivity: hashCode ... 70435669
I/BaseActivity: *****************end*********************
I/BaseActivity: *****************start*********************
I/BaseActivity: onCreate
I/BaseActivity: class name ... B_Activity
I/BaseActivity: task id ... 55
I/BaseActivity: hashCode ... 150908703
I/BaseActivity: *****************end*********************
I/BaseActivity: *****************start*********************
I/BaseActivity: onCreate
I/BaseActivity: class name ... StandardActivity
I/BaseActivity: task id ... 55
I/BaseActivity: hashCode ... 178376864
I/BaseActivity: *****************end*********************
I/BaseActivity: *****************start*********************
I/BaseActivity: onCreate
I/BaseActivity: class name ... A_Activity
I/BaseActivity: task id ... 55
I/BaseActivity: hashCode ... 27787325
I/BaseActivity: *****************end*********************
通过log发现Standard的启动模式每次都会创建一个新的Activity实例(hashCode不同),无论task中是否包含它的实例,并且都默认在一个task中。还有一种方式是在Activity中调用startActivity打开它自己,这种方式也是会创建新的实例。该模式是系统默认的Activity启动方式。
2.SingleTop(栈顶复用模式)
例:在Activity中调用startActivity打开它自己
SingleTopActivity-->A_Activity-->A_Activity-->A_Activity
I/BaseActivity: *****************start*********************
I/BaseActivity: onCreate
I/BaseActivity: class name ... SingleTopActivity
I/BaseActivity: task id ... 60
I/BaseActivity: hashCode ... 159258267
I/BaseActivity: *****************end*********************
I/BaseActivity: *****************start*********************
I/BaseActivity: onCreate
I/BaseActivity: class name ... A_Activity
I/BaseActivity: task id ... 60
I/BaseActivity: hashCode ... 70435669
I/BaseActivity: *****************end*********************
I/BaseActivity: *****************start*********************
I/BaseActivity: onNewIntent
I/BaseActivity: class name ... A_Activity
I/BaseActivity: task id ... 60
I/BaseActivity: *****************end*********************
I/BaseActivity: *****************start*********************
I/BaseActivity: onNewIntent
I/BaseActivity: class name ... A_Activity
I/BaseActivity: task id ... 60
I/BaseActivity: *****************end*********************
我们看到A_Activity被SingleTopActivity打开后,调用startActivitiy再次打开它自己(此时A_Activity是处于栈顶状态的),log中显示不会调用onCreate方法,而是调用了onNewIntent方法,将intent作为参数传进去。这就告诉我们SingleTop模式,假如栈顶中就是该Activity,不会再次创建新的实例,而是调用onNewIntent方法。并且task也不会发生改变。
另一种情况是没有在栈顶,跳转会有什么变化
SingleTopActivity-->A_Activity-->B_Activity-->StandardActivity-->A_Activity-->B_Activity
I/BaseActivity: *****************start*********************
I/BaseActivity: onCreate
I/BaseActivity: class name ... SingleTopActivity
I/BaseActivity: task id ... 61
I/BaseActivity: hashCode ... 159258267
I/BaseActivity: *****************end*********************
I/BaseActivity: *****************start*********************
I/BaseActivity: onCreate
I/BaseActivity: class name ... A_Activity
I/BaseActivity: task id ... 61
I/BaseActivity: hashCode ... 70435669
I/BaseActivity: *****************end*********************
I/BaseActivity: *****************start*********************
I/BaseActivity: onCreate
I/BaseActivity: class name ... B_Activity
I/BaseActivity: task id ... 61
I/BaseActivity: hashCode ... 232231149
I/BaseActivity: *****************end*********************
I/BaseActivity: *****************start*********************
I/BaseActivity: onCreate
I/BaseActivity: class name ... StandardActivity
I/BaseActivity: task id ... 61
I/BaseActivity: hashCode ... 184432887
I/BaseActivity: *****************end*********************
I/BaseActivity: *****************start*********************
I/BaseActivity: onCreate
I/BaseActivity: class name ... A_Activity
I/BaseActivity: task id ... 61
I/BaseActivity: hashCode ... 35966488
I/BaseActivity: *****************end*********************
I/BaseActivity: *****************start*********************
I/BaseActivity: onCreate
I/BaseActivity: class name ... B_Activity
I/BaseActivity: task id ... 61
I/BaseActivity: hashCode ... 175793491
I/BaseActivity: *****************end*********************
这种情况跟Standard模式完全一样,当有Activity不在栈顶的时候就会创建它的实例。
另:taskAffinity属性
Standard和singleTop启动模式都是在原任务栈中新建Activity实例,不会启动新的Task,即使你指定了taskAffinity属性。
taskAffinity标识了一个Activity所需任务栈的名字,默认情况下,所有Activity所需的任务栈的名字为应用的包名。
我们可以单独指定每一个Activity的taskAffinity属性覆盖默认值,一个任务的affinity决定于这个任务的根activity(root activity)的taskAffinity
在概念上,具有相同的affinity的activity(即设置了相同taskAffinity属性的activity)属于同一个任务
为一个activity的taskAffinity设置一个空字符串,表明这个activity不属于任何task
taskAffinity属性不对standard和singleTop模式有任何影响,即时你指定了该属性为其他不同的值,这两种启动模式下不会创建新的task(如果不指定即默认值,即包名)
3.SingleTask(栈内复用模式)
例:跳转顺序为SingleTaskActivity-->A_Activity-->B_Activity-->SingleTaskActivity
I/BaseActivity: *****************start*********************
I/BaseActivity: onCreate
I/BaseActivity: class name ... SingleTaskActivity
I/BaseActivity: task id ... 65
I/BaseActivity: hashCode ... 159258267
I/BaseActivity: *****************end*********************
I/BaseActivity: *****************start*********************
I/BaseActivity: onCreate
I/BaseActivity: class name ... A_Activity
I/BaseActivity: task id ... 65
I/BaseActivity: hashCode ... 70435669
I/BaseActivity: *****************end*********************
I/BaseActivity: *****************start*********************
I/BaseActivity: onCreate
I/BaseActivity: class name ... B_Activity
I/BaseActivity: task id ... 65
I/BaseActivity: hashCode ... 232231149
I/BaseActivity: *****************end*********************
I/BaseActivity: *****************start*********************
I/BaseActivity: onNewIntent
I/BaseActivity: class name ... SingleTaskActivity
I/BaseActivity: task id ... 65
I/BaseActivity: hashCode ... 159258267
I/BaseActivity: *****************end*********************
我们将SingleTaskActivity设置成了SingleTask模式,从B_Activity再次启动SingleTaskActivity时,由于栈内已经有它的实例,因此这里只调用了它的onNewIntent方法,不会创建新的实例。再通过命令adb shell dumpsys activity activities 查看当前存在的Activity。
Running activities (most recent first):
TaskRecord{a1cd706 #65 A=com.ly.teststartactivity U=0 StackId=1 sz=1}
Run #0: ActivityRecord{415c55d u0 com.ly.teststartactivity/.SingleTaskActivity t65}
我们发现就剩下SingleTaskActivity了,位于它之上的A_Activity和B_Activity都已经被销毁了。
这时往回看,这几个Activity没有设置taskAffinity属性,即默认值是包名,下面我们将改变它的taskAffinity属性查看是否有变化
SingleTaskActivity 设置 android:taskAffinity="com.test.singletask(不同于包名)
启动顺序SingleTaskActivity-->A_Activity-->B_Activity-->SingleTaskActivity-->A_Activity-->B_Activity
都设置成SingleTask启动模式
I/BaseActivity: *****************start*********************
I/BaseActivity: onCreate
I/BaseActivity: class name ... SingleTaskActivity
I/BaseActivity: task id ... 67
I/BaseActivity: hashCode ... 159258267
I/BaseActivity: *****************end*********************
I/BaseActivity: *****************start*********************
I/BaseActivity: onCreate
I/BaseActivity: class name ... A_Activity
I/BaseActivity: task id ... 68
I/BaseActivity: hashCode ... 70435669
I/BaseActivity: *****************end*********************
I/BaseActivity: *****************start*********************
I/BaseActivity: onCreate
I/BaseActivity: class name ... B_Activity
I/BaseActivity: task id ... 68
I/BaseActivity: hashCode ... 232231149
I/BaseActivity: *****************end*********************
I/BaseActivity: *****************start*********************
I/BaseActivity: onNewIntent
I/BaseActivity: class name ... SingleTaskActivity
I/BaseActivity: task id ... 67
I/BaseActivity: hashCode ... 159258267
I/BaseActivity: *****************end*********************
I/BaseActivity: *****************start*********************
I/BaseActivity: onNewIntent
I/BaseActivity: class name ... A_Activity
I/BaseActivity: task id ... 68
I/BaseActivity: hashCode ... 70435669
I/BaseActivity: *****************end*********************
I/BaseActivity: *****************start*********************
I/BaseActivity: onCreate
I/BaseActivity: class name ... B_Activity
I/BaseActivity: task id ... 68
I/BaseActivity: hashCode ... 246680013
I/BaseActivity: *****************end*********************
log告诉我们taskAffinity不同就会生成不同的task,当B_Activity再次启动SingleTaskActivity时,不会创建新的实例而是回调onNewIntent,证明系统已经知道它有实例存在某个task中,然后再次启动A_Activity,由于A_Activity也是SingleTask所以它也不会创建新的实例,并且将之前同task中的B_Activity销毁,这也就是为什么最后启动B_Activity时创建了一个新的实例。
SingleTask启动模式总结:
首先启动Activity之前会判断该Activity的任务栈名字是否存在(一般默认是包名)
如果不存在,创建新的任务栈,并创建实例
如果存在,查询该任务栈里面是否有它的实例
如果没有实例,创建实例
如果有实例,那么移除在它之上的Activity(出栈),回调onNewIntent
注:不同应用之间的Activity假如都拥有相同的taskAffinity,那么他们也会被分配到同一个task中。
4.SingleInstance(全局唯一模式)
设置Activity启动模式为SingleInstance,那么就会创建一个新的task给这个Activity,并且全局都会是唯一的,该task只属于这一个Activity。它拥有SingTask所有特性。如果task没有被销毁,那么始终就会是这一个实例,如果被销毁了,就会创建一个新的task。