Android 学习笔记 —— Activity 的启动模式
Activity 的启动模式
定义 Activity 的启动模式有两种方式:
- 使用 AndroidManifest.xml 清单文件。
- 使用 Intent 标志。
优先级:Intent 标志设定 > AndroidManifest 设定
使用 AndroidManifest.xml 清单文件定义启动模式
在 AndroidManifest.xml 文件中通过给 <activity>
标签指定 android:launchMode
属性来选择启动模式。使用该方式主要有四种启动模式,分别为 standard
、singleTop
、singleTask
和 singleInstance
。
<activity
...
android:launchMode="" />
<!-- android:launchMode="standard" -->
<!-- android:launchMode="singleTop" -->
<!-- android:launchMode="singleTask" -->
<!-- android:launchMode="singleInstance" -->
standard
(默认)
每次都创建一个新的实例压入 Task 栈中。singleTop
(栈顶复用)
如果要新建的 Activity(目标 Activity)在栈顶,那么就不会重复创建新的实例,而是通过onNewIntent()
方法接收 Intent 并复用栈顶的实例。注意无法通过返回键回到接收新 Intent 前的状态,且如果目标 Activity 不在栈顶还是会重新创建一个实例。
适用场景:适合开启渠道多、多应用开启调用的 Activity。常见于社交应用中的通知栏消息推送行为等。singleTask
(栈内复用)
创建一个新的 Task 任务栈,并在新 Task 中实例化目标 Activity。但是,如果目标 Activity 在其他 Task 任务栈中有已存在的实例,则将该 Activity 实例之上的所有 Activity 从任务栈中弹出,通过调用其onNewIntent()
方法将 Intent 转送到该现有实例,让目标 Activity 获得焦点。
适用场景:程序主界面、耗费系统资源的 Activity。如视频播放界面等。singleInstance
(全局单例)
为目标 Activity 创建一个新的 Task 任务栈然后放入其中,并让目标 Activity 获得焦点。新的 Task 任务栈有且只有这一个 Activity 实例。如果已经创建过目标 Activity 实例,则不会再创建新的 Task 任务栈,而是将之前创建的 Activity 唤醒。
适用场景:适用于需要与程序分离开的页面,不应该用作中间页面进行跳转。常用于外部分享到社交应用的选择界面(选择分享给谁),系统应用来电呼叫界面、闹钟提醒界面等。
使用 Intent 标志定义启动模式
在用于启动 Activity 的 Intent 中,使用 setFlags()/addFlags()
方法添加标志来设定该 Activity 的启动模式。该方式可使用的标志主要有 FLAG_ACTIVITY_NEW_TASK
、FLAG_ACTIVITY_CLEAR_TASK
、FLAG_ACTIVITY_SINGLE_TOP
和 FLAG_ACTIVITY_CLEAR_TOP
。
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-
FLAG_ACTIVITY_NEW_TASK
:检查是否存在 taskAffinity 值与目标 Activity 相同的 Task,存在则新建目标 Activity 实例并压入该任务栈栈顶,不存在则创建一个 taskAffinity 值与目标 Activity 相同的 Task 任务栈并将新建目标 Activity 实例压入新任务栈栈顶。默认情况下,同一个应用所有 Activity 的 taskAffinity 值都是应用包名。- 如果 Intent 没有设置该 FLAG 标志,
startActivity(Intent)
时不会因为 taskAffinity 值不同而创建一个新 Task 任务栈。 - 非 Activity(如 Service 和 Broadcast) 中启动 Activity 需要添加此标志才能成功启动。
- 如果 Intent 没有设置该 FLAG 标志,
-
FLAG_ACTIVITY_CLEAR_TASK
: 该标记只能与 FLAG_ACTIVITY_NEW_TASK 结合使用。任何与目标 Activity 相关联的 Task 任务栈都会被清空,新 Activity 实例将会被压入一个空的任务栈的栈底。 -
FLAG_ACTIVITY_SINGLE_TOP
:与singleTop
产生的行为相同。 -
FLAG_ACTIVITY_CLEAR_TOP
:如果要启动的 Activity 已经在当前任务中运行,则不会启动该 Activity 的新实例,而是会销毁位于它之上的所有其他 Activity,并通过onNewIntent()
将此 Intent 传送给它现在位于栈顶的已恢复实例。
Intent 标志还有不少,搭配使用可以实现很多效果,暂不细究。