Activity 的 LaunchMode
Android 目前有四中启动模式:standard、singleTop、singleTask、singleInstance。
- standard:标准模式,也是系统默认模式。每次启动一个 Activity 都会重新创建一个新的实例,被创建的实例的生命周期符合典型的情况下的 Activity 的生命周期。这种模式下,谁启动了这个 Activity,那么这个 Activity,那么这个 Activity 就运行在启动它的那个 Activity 所在的任务栈中。如果用 ApplicationContext 去启动 standard 模式的 Activity 会报错,因为非 Activity 类型的 context 并没有任务栈。 这种情况在安卓高版本,如 7.0,8.0 是不会出错的,在安卓 4.4 是会报错的,怀疑安卓修改了非 Activity 启动 Activity 的机制。
- singleTop:栈顶复用模式。如果新的 Activity 已经位于任务栈的栈顶,那么此 Activity 不会被重新创建,同时它的 onNewIntent 方法会被调用,通过此方法的参数我们可以取出当前请求的信息。这个 Activity 的 onCreate、onStart 不会被系统调用,因为它没有发生改变,如果新Activity的实例已存在,但不是位于栈顶,那么新 Activity 仍然会重新创建。
启动栈顶 Activity 的生命周期如下。
onPause
onNewIntent
onResume
- singleTask:栈内复用模式。只要 Activity 在一个栈中存在,那么多次启动此 Activity 都不会重新创建实例,系统也会回调其 onNewIntent。当一个具有 singleTask 模式的 Activity 请求启动后,系统首先会寻找是否存在 A 想要的任务栈,如果不存在就创建一个任务栈,并将新创建的实例放入栈中。如果存在其所需要的任务栈,这个栈中要是有该实例存在,就会把其调到栈顶并调用它的 onNewIntent 方法,如果不存在,就创建该实例并将其压入栈中。
- singleInstance:单实例模式,加强版的 singleTask,拥有 singleTask 模式的所有特征,除此之外,具有这种模式的 Activity 只能独立的位于一个任务栈中,后续的请求都会创建新的 Activity,除非这个独特的任务栈被系统销毁。
TaskAffinity 这个参数标识了一个 Activity 所需要的任务栈的名字,默认情况下,所有 Activity 所需要的任务栈的名字为应用的包名。
<activity android:name=".SecondActivity"
android:taskAffinity="com.example.testandroid.task1"
android:launchMode="singleTask"/>
指定启动模式
方法一:通过 AndroidMenifest 为 Activity 指定启动模式。
<activity .
android:name=".LifecycleActivity"
android:launchMode="singleTask"/>
方法二:通过在 Intent 中设置标志位来位 Activity 指定启动模式。
Intent intent = new Intent(MyApplication.this, LifecycleActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
这两种方法都能为 Activity 指定启动模式,优先级上第二种方法要高于第一种,如果两个同时存在,以第二种方式为准;其次,第一种方法无法直接为 Activity 设定 FLAG_ACTIVITY_CLEAR_TOP 标识,而第二种方式无法为 Activity 指定 singleInstance 模式。
Activity 的 Flags
设定 Activity 的启动模式
字段 | 作用 |
---|---|
FLAG_ACTIVITY_NEW_TASK | 为 Activity 指定 singleTask |
FLAG_ACTIVITY_SINGLE_TOP | 为 Activity 指定 singleTop |
影响 Activity 的运行状态
字段 | 作用 |
---|---|
FLAG_ACTIVITY_CLEAR_TOP | 具有此标记的 Activity,当它启动时,在同一个任务栈上它上面的 Activity 都要出栈。singleTask 启动模式默认具有此标记位的效果 |
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | 具有这个标记的 Activity 不会出现在 历史 Activity 的列表中,当某些情况下不希望用户通过历史列表回到我们的 Activity 的时候有用,等同于在 XML 中指定 Activity 的属性 android:excludeFromRecents="true" |