05-Activity任务栈与启动模式
Activity 任务栈与四种启动模式
1. 什么是任务栈?
任务栈是 Android 用来管理 Activity 返回关系的一种结构。
特点是:
后进先出
最后打开的 Activity 在栈顶
按返回键时,栈顶 Activity 出栈
例如:
A → B → C
任务栈可以理解为:
顶部 C
B
底部 A
按返回键时:
C 出栈,回到 B
B 出栈,回到 A
A 出栈,任务结束
2. 为什么需要启动模式?
默认情况下,每次启动 Activity 都会创建一个新实例。
例如:
A → B → B → B
如果 B 被频繁打开,就会产生多个 B 实例。
可能造成:
内存浪费
返回栈混乱
页面重复
用户体验不好
启动模式就是用来控制 Activity 是否复用、如何进入任务栈。
3. standard:标准模式
standard 是默认启动模式。
特点:
每次启动都会创建新实例
不管栈中是否已经存在
例如当前任务栈:
A B C
再次启动 C:
A B C C
配置方式:
<activity
android:name=".DetailActivity"
android:launchMode="standard" />
适合场景:
普通详情页
普通表单页
大多数普通页面
4. singleTop:栈顶复用模式
singleTop 的规则:
如果目标 Activity 已经在栈顶,就复用它;
如果目标 Activity 不在栈顶,就创建新实例。
当前栈:
A B C
再次启动 C:
A B C
不会创建新 C,而是回调:
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
}
但是如果当前栈是:
A C B
再次启动 C:
A C B C
因为 C 不在栈顶,所以仍会创建新实例。
适合场景:
通知点击打开的页面
扫码页面
搜索页面
防止栈顶页面重复打开
5. singleTask:栈内复用模式
singleTask 的规则:
只要目标 Activity 在任务栈中已经存在,就复用它;
并且把它上面的 Activity 全部出栈。
当前栈:
A B C D
如果 B 是 singleTask,再次启动 B:
A B
C 和 D 会被移除,B 会收到:
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
}
适合场景:
首页 MainActivity
主入口页面
需要栈内唯一的页面
浏览器主页类页面
6. singleInstance:单实例模式
singleInstance 是更强的 singleTask。
特点:
全局只有一个实例
独占一个任务栈
其他 Activity 不会和它放在同一个任务栈
适合场景较少,常见于:
来电页面
闹钟页面
独立入口页面
需要和主任务栈隔离的页面
一般业务开发中不要随便使用,因为它会让返回栈行为变复杂。
7. 四种启动模式对比
| 启动模式 | 是否每次新建 | 复用规则 | 典型特点 |
|---|---|---|---|
standard |
是 | 不复用 | 默认模式 |
singleTop |
不一定 | 栈顶存在才复用 | 防止栈顶重复 |
singleTask |
不一定 | 栈内存在就复用,并清理上方页面 | 栈内唯一入口 |
singleInstance |
不一定 | 全局复用 | 独占任务栈 |
8. 如何配置启动模式?
在 AndroidManifest.xml 中配置:
<activity
android:name=".MainActivity"
android:launchMode="singleTask" />
也可以通过 Intent Flag 影响启动行为:
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
9. 纠错:FLAG_ACTIVITY_NEW_TASK 不等于 singleTask
原 PDF 中提到:
ApplicationContext 启动 standard Activity 时加 FLAG_ACTIVITY_NEW_TASK,
实际相当于 singleTask 启动。
这个说法不严谨。
更准确地说:
FLAG_ACTIVITY_NEW_TASK 会影响 Activity 进入哪个 task。
系统会寻找或创建一个合适的任务栈。
它不等价于 manifest 中的 singleTask。
singleTask 是 Activity 的启动模式,强调“栈内复用并清理上方页面”。
FLAG_ACTIVITY_NEW_TASK 是启动标记,强调“从新的或已有合适 task 启动”。
两者可能在某些现象上相似,但不能直接划等号。
10. taskAffinity 的影响
singleTask、FLAG_ACTIVITY_NEW_TASK 等行为还可能受到 taskAffinity 影响。
taskAffinity 可以理解为:
Activity 更倾向于进入哪个任务栈。
如果不理解 taskAffinity,很多启动模式现象会看起来很乱。
普通业务开发中建议:
不要随意修改 taskAffinity
不要随意使用 singleInstance
不要为了“解决跳转问题”滥用启动模式
优先用清晰的页面设计和显式返回逻辑解决问题。
11. 总结
standard:每次都新建
singleTop:栈顶有就复用
singleTask:栈内有就复用,并清掉上面的页面
singleInstance:自己独占任务栈,全局唯一
记忆口诀:
Top 看栈顶,Task 看栈内,Instance 单独住。
参考来源
- 原始 PDF:《01、Activity知识总结.pdf》
- Android 官方文档:Activity 生命周期
https://developer.android.com/guide/components/activities/activity-lifecycle - Android 官方文档:Activity API Reference
https://developer.android.com/reference/android/app/Activity - Android 官方文档:处理配置变更
https://developer.android.com/guide/topics/resources/runtime-changes - Android 官方文档:
<activity>manifest 配置
https://developer.android.com/guide/topics/manifest/activity-element - Android 官方文档:Tasks and back stack
https://developer.android.com/guide/components/activities/tasks-and-back-stack - Android 官方文档:Services overview
https://developer.android.com/develop/background-work/services