Activity的LaunchMode和Intent Flags详解

LaunchMode

standard

这是launchMode的默认值,Activity不包含android:launchMode或者显示设置为standard的Activity就会使用这种模式。一旦设置成这个值,每当有一次Intent请求,就会创建一个新的Activity实例

singleTop

singleTop其实和standard几乎一样,使用singleTop的Activity也可以创建很多个实例。唯一不同的就是,如果调用的目标Activity已经位于调用者的Task的栈顶,则不创建新实例,而是使用当前的这个Activity实例,并调用这个实例的onNewIntent方法。

singleTask

singleTask这个模式和前面提到的standard和singleTop截然不同。使用singleTask启动模式的Activity在系统中只会存在一个实例。如果这个实例已经存在,那么在Activity回退栈中,所有位于该Activity上面的Activity实例都将被销毁掉(销毁过程会调用Activity生命周期回调),intent就会通过onNewIntent传递到这个Activity。否则新的Activity实例被创建。

设置了singleTask启动模式的Activity,它在启动的时候,会先在系统中查找属性值affinity等于它的属性值taskAffinity的Task存在; 如果存在这样的Task,它就会在这个Task中启动,否则就会在新的任务栈中启动。因此, 如果我们想要设置了singleTask启动模式的Activity在新的任务中启动,就要为它设置一个独立的taskAffinity属性值。Activity默认的taskAffinity属性为应用的包名。

singleInstance

这个模式和singleTask差不多,因为他们在系统中都只有一份实例。唯一不同的就是存放singleInstance Activity实例的Task只能存放一个该模式的Activity实例。如果从singleInstance Activity实例启动另一个Activity,那么这个Activity实例会放入其他的Task中。

Intent Flags

FLAG_ACTIVITY_SINGLE_TOP

同singleTop启动模式。

FLAG_ACTIVITY_CLEAR_TOP

如果在ABCD的堆栈状态下,以该标识启动B,则会销毁CD,且B也是重新创建的(与singleTask有区别)

FLAG_ACTIVITY_BROUGHT_TO_FRONT

这个Flag主要用来改变Task堆栈顺序,如果在ABCD的状态下,以该标识启动B,则会成为ACDB,且B不会重新创建

FLAG_ACTIVITY_NEW_TASK

和singleTask类似,也需配合taskAffinity使用,但不会清除被打开activity之上的activity。FLAG_ACTIVITY_NEW_TASK配合FLAG_ACTIVITY_CLEAR_TOP、FLAG_ACTIVITY_SINGLE_TOP和singleTask的作用完全一致。

Tip

singleTask和FLAG_ACTIVITY_NEW_TASK在同一个应用内需要加上taskAffinity才有作用,如果activity加上了singleTask或Intent中加上了FLAG_ACTIVITY_NEW_TASK,然后被A应用打开则会新开一个栈来放置,此时不需要指定taskAffinity,不加singleTask或FLAG_ACTIVITY_NEW_TASK则会和A处于同一个栈中。