在多Activity开发中,有可能是自己应用之间的Activity跳转,或者夹带其他应用的可复用Activity。可能会希望跳转到原来某个Activity实例,而不是产生大量重复的Activity。这需要为Activity配置特定的加载模式,而不是使用默认的加载模式。

Activity有四种加载模式,在AndroidManifest.xml文件中activity元素的android:launchMode属性进行配置:

“standard”

“ingleTop”

“singleTask”

“singleInstance”

这四种模式又分为两类,standard和singleTop属于一类,singleTask和singleInstance 属于一类,他们主要有以下不同

1、如何决定所属Task

Standard 和 singleTop 的activity的目标task和收到的Intent的发送者在同一个Task内。除非intent包括参数FLAG_ACTIVITY_NEW_TASK。而且如果提供了FLAG_ACTIVITY_NEW_TASK参数,会启动到别的Task里。

singleTask和singleInstance 总是把Activity作为一个task的根元素,他们不会被启动到一个其他的task里。

2、是否允许多个实例

Standard 和 singleTop 可以被实例化多次,并且存在于不同的task中,且一个task可以包括一个Activity的多个实例。

singleTask和singleInstace则限制只生成一个实例,并且是task的根元素。

singleTop要求如果创建intent的时候栈顶已经有要创建的Activity的实例,则将Intent发送给该实例,而不发送给新的实例

3、是否允许其它activity存在于本Task内

singleInstance 独占一个task,其它activity不能存在那个task里,如果它启动了一个新的avtivity,不管新的Activity的lanuch mode如何,新的Activity都将会得到别的task里运行(如同加FLAG_ACTIVITY_NEW_TASK参数)

另外三种模式。则可以和其它Activity共存。

4、是否每次都生成新实例

standard对于每一个启动Intent都会生成一个Activity的新实例。

singleTop的avtivity如果在task的栈顶的话,则不生成新的该实例。

singleInstace是其所在栈的唯一Activity,它会每次都被重用。

singleTask如果在栈顶,则接受Intent,否则,该Intent会被丢弃,但是访Task仍会回到前台。

Lanuch ModeLanuch Mode是否允许多个实例是否每次都生成新实例是否允许其他Activity存在于本Task内如何决定所属Task
standard可以被多次实例化,同一个Activity中的不同实例可以存在于不同的Task中,同一个Task也可以存在多个Activity实例允许存放于StartActivity()的Task。除非设置FLAG_ACTIVITY_NEW_TASK标识
singleTop同Standard如果寄存Activity的栈顶为该Activity,则直接用该Activity实例;否则创建新实例允许同Standard
singleInstace不能有多个实例,由于该模式下Activity总是存在于栈顶,所以Activity在同一实例里至多只有一个实例只有在第一次才创建新的实例,其他情况复用该Activity允许。如果存放singleTask的寄存Task内,相应一个工Intent时,如果singleTask位于栈顶,则处理Intent,否则会丢失Intent,但该Task会处于前台存放新的Task内,并且位于该Task的根,不会存放于其他的Task。
singleTask同singleTask同singleTask不允许同singleTask

standard: 标准模式,一调用startActivity()方法就会产生一个新的实例。

singleTop: 如果已经有一个实例位于Activity栈的顶部时,就不产生新的实例,而只是调用Activity中的newInstance()方法。如果不位于栈顶,会产生一个新的实例。

singleTask: 会在一个新的task中产生这个实例,以后每次调用都会使用这个,不会去产生新的实例了。

singleInstance: 这个跟singleTask基本上是一样,只有一个区别:在这个模式下的Activity实例所处的task中,只能有这个activity实例,不能有其他的实例。

相关的代码中也有一些标志可以使用,比如我们想只启用一个实例,则可以使用 Intent.FLAG_ACTIVITY_REORDER_TO_FRONT 标志,这个标志表示:如果这个activity已经启动了,就不产生新的activity,而只是把这个activity实例加到栈顶来就可以了。

Intent intent = new Intent(ReorderFour.this, ReorderTwo.class);

intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);

startActivity(intent);

Activity的加载模式受启动Activity的Intent对象中设置的Flag和manifest文件中Activity的元素的特性值交互控制。

下面是影响加载模式的一些特性

核心的Intent Flag有:

FLAG_ACTIVITY_NEW_TASK

FLAG_ACTIVITY_CLEAR_TOP

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

FLAG_ACTIVITY_SINGLE_TOP

核心的特性有:

taskAffinity

launchMode

allowTaskReparenting

clearTaskOnLaunch

alwaysRetainTaskState

finishOnTaskLaunch