Activity 的 " 启动模式 "


一、LaunchMode

我们可以在 AndroidManifest.xml 中通过给 <activity> 标签指定 android:launchMode 属性来选择启动模式。

1.1 standard:默认启动模式

standard 是活动默认的启动模式,在不进行显式指定的情况下,所有活动都会自动使用这种启动模式。我们知道 Android 是使用返回栈来管理活动的,在 standard 模式下,每当启动一个新的活动,它就会在返回栈中入栈,并处于栈顶的位置。

对于使用 standard 模式的活动,系统不会在乎这个活动是否已经在返回栈中存在,每次启动都会创建该活动的一个新实例。

standard.png

1.2 singleTop:栈顶复用模式

有没有觉得 standard 模式似乎不太合理,活动明明已经在栈顶了,为什么再次启动的时候还要创建一次新的活动实例呢?当然,这只是系统默认的一种启动模式而已,我们完全可以根据自己的要求进行修改,比如说我们可以使用 singleTop 模式。

当活动的启动模式指定为 singleTop,在启动活动时如果发现返回栈的栈顶已经是该活动,则认为可以直接使用它,直接调用 onNewIntent() 方法来实现重用,不会再创建新的活动实例。

singleTop.png

1.3 singleTask:栈内复用模式

使用 singleTop 模式可以很好的解决重复创建栈顶活动的问题,但还是存在不合理的地方:如果活动处于栈顶,那么不会再重新创建一个新的实例,但如果不处于栈顶,则会重新创建

所以我们自然要考虑一个问题,有没有什么方法可以让某个活动在整个应用程序的上下文中只存在一个实例呢?当然有,我们可以借助 singleTask 模式来实现。

当活动的启动模式指定为 singleTask,每次启动该活动时系统 首先会在返回栈中检查是否存在该活动的实例,如果发现已经存在则直接调用 onNewIntent() 方法来实现重用实例,活动置于栈顶,并把在这个活动之上的所有活动统统出栈,如果没有发现就会创建一个新的活动实例。

singleTask.png

1.4 singleInstance:全局唯一模式

singleInstance 模式应该算是 4 个启动模式中最特殊也最复杂的一个了。不同于以上 3 种启动模式,指定为 singleInstance 模式的活动会在一个新栈中创建该 Activity 的实例,并让多个应用共享该栈中的 Activity 实例

singleInstance.png

二、Intent flag

在 Android 中,我们除了在清单文件 AndroidManifest.xml 中配置 launchMode(静态设置),完全可以通过设置 Intent.setFlags(int flags) 来设置 Activity 的启动模式(动态设置)。

需要注意的是:通过代码来设置 Activity 的启动模式的方式,优先级比清单文件设置更高。

Flag 说明
FLAG_ACTIVITY_NEW_TASK 这个标识会使新启动的 Activity 独立创建一个 Task。
FLAG_ACTIVITY_CLEAR_TOP 这个标识会使新启动的 Activity 检查是否存在于 Task 中,如果存在则清除其之上的 Activity,使它获得焦点,并不重新实例化一个 Activity,一般结合 FLAG_ACTIVITY_NEW_TASK 一起使用。
FLAG_ACTIVITY_SINGLE_TOP 等同于 launcherMode 属性设置为 singleTop。