Activity 启动流程
问题
startActivity 的完整调用链是什么?LaunchMode 如何影响 Task 栈?
答案
startActivity 调用链
LaunchMode
| 模式 | 行为 | Intent Flag 等价 | 典型场景 |
|---|---|---|---|
| standard | 每次创建新实例 | - | 普通页面 |
| singleTop | 栈顶复用,onNewIntent | FLAG_ACTIVITY_SINGLE_TOP | 通知页、搜索 |
| singleTask | 栈内复用,清除其上的 Activity | FLAG_ACTIVITY_CLEAR_TOP | 首页 |
| singleInstance | 独占 Task,全局唯一 | - | 来电界面 |
singleTask 行为详解
taskAffinity
<!-- 指定 Activity 所属的 Task -->
<activity
android:name=".DetailActivity"
android:taskAffinity="com.example.detail"
android:launchMode="singleTask" />
taskAffinity 定义 Activity 的"亲和力"——当 launchMode 为 singleTask 时,系统会在匹配的 affinity Task 中启动该 Activity。默认所有 Activity 的 affinity 为应用包名。
常见面试问题
Q1: onNewIntent 什么时候会被调用?
答案:
当 Activity 已经存在且被复用时调用:
singleTop:Activity 在栈顶时收到新的 IntentsingleTask:Activity 在栈内被找到并复用singleInstance:全局唯一实例被复用
调用顺序:onNewIntent() → onResume()。注意 getIntent() 仍然返回旧的 Intent,需要在 onNewIntent 中调用 setIntent(intent) 更新。
Q2: FLAG_ACTIVITY_NEW_TASK 的作用?
答案:
从非 Activity 的 Context(如 Service、BroadcastReceiver、Application)启动 Activity 时必须添加此 Flag,因为这些 Context 没有关联的 Task。此 Flag 会在目标 Activity 的 taskAffinity 对应的 Task 中启动(如果 Task 不存在则创建新 Task)。
Q3: 如何从最近任务列表中隐藏 Activity?
答案:
在 <activity> 中设置 android:excludeFromRecents="true",或在启动 Intent 中添加 FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS。适合临时页面如授权页面。