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 的影响

singleTaskFLAG_ACTIVITY_NEW_TASK 等行为还可能受到 taskAffinity 影响。

taskAffinity 可以理解为:

Activity 更倾向于进入哪个任务栈。

如果不理解 taskAffinity,很多启动模式现象会看起来很乱。

普通业务开发中建议:

不要随意修改 taskAffinity
不要随意使用 singleInstance
不要为了“解决跳转问题”滥用启动模式

优先用清晰的页面设计和显式返回逻辑解决问题。


11. 总结

standard:每次都新建
singleTop:栈顶有就复用
singleTask:栈内有就复用,并清掉上面的页面
singleInstance:自己独占任务栈,全局唯一

记忆口诀:

Top 看栈顶,Task 看栈内,Instance 单独住。

参考来源