外观
启动模式和 Intent Flag 怎样影响任务栈?
标准回答
启动模式是 Activity 在 Manifest 中声明的默认启动规则,Intent flags 是这一次启动请求附带的规则。两者共同影响“新建还是复用实例、进入哪个任务、哪些页面被移除”;它们管理的是页面和任务,并不直接决定是否创建新进程。
常用模式中,standard 通常创建新实例;singleTop 仅在目标已经位于所选任务栈顶时复用,否则仍创建;singleTask 按任务和实例匹配规则查找,存在适用实例时会复用并移除其上的页面,没有时再按规则创建。复用已有实例时,新的启动参数通常通过 onNewIntent 交给它,不重新走一次完整的 onCreate。
FLAG_ACTIVITY_NEW_TASK 让启动按新任务相关规则选择或创建任务,也可能复用已有匹配任务。FLAG_ACTIVITY_SINGLE_TOP 让这次启动具备栈顶复用语义。FLAG_ACTIVITY_CLEAR_TOP 在目标任务中找到已有目标后清理它上面的页面;如果目标是 standard 且没有结合 SINGLE_TOP 等复用条件,目标自身也可能被移除再重建。FLAG_ACTIVITY_CLEAR_TASK 与 NEW_TASK 配合,可以清空目标任务后以新页面作为入口。
另外,singleInstance 的实例独占其任务,其他 Activity 不与它放在同一任务;singleInstancePerTask 强调实例作为任务根,同一任务只保留一个该实例,但在相应启动 flags 下可以跨任务创建多个实例。这些模式适合明确的导航需求,不应为了猜测能提高启动速度而随意使用。
例如当前 A → B → C,再打开 B 并希望复用原 B、移除 C,可以在匹配任务的前提下使用 CLEAR_TOP 与 SINGLE_TOP,并在 B.onNewIntent 中处理新参数。最终要验证任务归属与返回行为,不能只看到页面打开成功就认为规则正确。
关键机制
- NEW_TASK 要求在合适的任务中启动,可能复用已有任务,并不总是创建新进程或新实例。
- CLEAR_TOP 找到栈内目标并清理其上的页面;目标是否保留还与启动模式、SINGLE_TOP 等组合有关。
- 设计跳转时明确入口、任务归属、返回预期和重复点击;不要只根据某一次观察猜测完整规则。
通俗例子
A → B → C 后再次打开 B,若希望返回已有 B 并移除 C,可根据需求组合 CLEAR_TOP / SINGLE_TOP,并在 onNewIntent 更新数据。
追问与回答
CLEAR_TOP 和 SINGLE_TOP 有什么关键区别?
SINGLE_TOP 只关心目标是否已经在所选任务栈顶,不会帮你清理中间页面。CLEAR_TOP 会在目标存在时清理它上面的页面,但是否保留原目标实例还要看启动模式和其他 flags。组合使用可以表达“先清掉上层,再复用目标”的常见需求。
为什么 onNewIntent 收到新参数,getIntent 还是旧的?
onNewIntent 的参数是这次新收到的 Intent,而 Activity 已持有的 Intent 不会因此在所有用法中自动变成你期望的新值。如果后续逻辑依赖 getIntent,可以在 onNewIntent 中按需求调用 setIntent(intent),并明确刷新哪些页面状态,避免只更新一部分数据。
易混淆点
启动模式不是性能优化开关。NEW_TASK 是否改变耗时,要看实际复用路径和测量结果。
参考资料
内容来源
- Android 技术札记 · 原条目
launchmode