我们知道,在AndroiManifest.xml中设置AActivity的launchmode为SingleTask后,若Activity启动过程为:
A->B->C->A
当我们再次处于A Activity时:
B和C会执行onDestroy()
A会执行onNewIntent()、onStart()、onResume()
即B、C销毁了,而A没有重新创建,而是复用了之前一开始的实例。
但有时候我们希望能够灵活一点,有时候A的启动模式是SingleTask,有时候不是。
这时候我们就可以用到Intent.FLAG这个概念。
Intent有以下几种常见的flags:
-
FLAG_ACTIVITY_NEW_TASK:
当Intent对象包含这个标记时,系统会寻找或创建一个新的task来放置目标Activity,寻找时依据目标Activity的taskAffinity属性进行匹配,如果找到一个task的taskAffinity与之相同,就将目标Activity压入此task中,如果查找无果,则创建一个新的task,并将该task的taskAffinity设置为目标Activity的taskActivity,将目标Activity放置于此task。注意,如果同一个应用中Activity的taskAffinity都使用默认值或都设置相同值时,应用内的Activity之间的跳转使用这个标记是没有意义的,因为当前应用task就是目标Activity最好的宿主。
可以这样理解:根据Activity Affinity判断是否需要创建新的Task,然后再创建新的Activit实例放进去。
-
FLAG_ACTIVITY_CLEAR_TOP:
当Intent对象包含这个标记时,如果在当前栈中发现存在Activity实例,则清空这个实例之上的Activity,使其处于栈顶。这样一看似乎和SingleTask一样,但是两者区间是有区别的。
在使用默认的“standard”启动模式下,如果没有在Intent使用到FLAG_ACTIVITY_SINGLE_TOP标记,那么它将关闭后重建,如果使用了这个FLAG_ACTIVITY_SINGLE_TOP标记,则会使用已存在的实例;对于其他启动模式,无需再使用FLAG_ACTIVITY_SINGLE_TOP,它都将使用已存在的实例,Intent会被传递到这个实例的onNewIntent()中。
简单点理解:FLAG_ACTIVITY_CLEAR_TOP表示启动的Activity会将Task中位于其上的Activity都强制出栈,使其自身位于栈顶。在Standard模式下,如果原来的Activity栈顺序为 A -> B1 -> D, 此时D通过FLAG_ACTIVITY_CLEAR_TOP启动B,则栈顺序为A -> B2。对于同时设置了FLAG_ACTIVITY_SINGLE_TOP,则栈顺序为 A-> B1(此时回调onNewIntent()…),此时效果与Activity启动模式中的singleTask相同。
-
FLAG_ACTIVITY_SINGLE_TOP:
当task中存在目标Activity实例并且位于栈的顶端时,不再创建一个新的,直接利用这个实例。我们在上边的例子中也有讲到。目前发现与Activity启动模式中的singleTop效果相同。
综上:
-
如Activity的启动模式为standard,则需要使用
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP|Intent.FLAG_ACTIVITY_CLEAR_TOP)
去启动Activity来实现SingleTask的效果,但**(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP)更佳**,因为SINGLE_TOP和CLEAR_TOP都是针对当前TASK而言。NEW_TASK则可以找到其他栈上的实例来复用(将Activity实例上的其他Activity退栈,然后将含有Activity实例的后台TASK中的Activity加到前台栈中)。 -
如Activity的启动模式为standard之外的其他三种(singleTop、singleTask、singleInstance)
只需要intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)去启动Activity来实现SingleTask的效果
注意:
上述的
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP|Intent.FLAG_ACTIVITY_CLEAR_TOP)
并不能分开写成
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
否则启动standard模式下的Activity将会重建。