跳到主要内容

Activity 启动流程

问题

startActivity 的完整调用链是什么?LaunchMode 如何影响 Task 栈?

答案

startActivity 调用链

LaunchMode

模式行为Intent Flag 等价典型场景
standard每次创建新实例-普通页面
singleTop栈顶复用,onNewIntentFLAG_ACTIVITY_SINGLE_TOP通知页、搜索
singleTask栈内复用,清除其上的 ActivityFLAG_ACTIVITY_CLEAR_TOP首页
singleInstance独占 Task,全局唯一-来电界面

singleTask 行为详解

taskAffinity

<!-- 指定 Activity 所属的 Task -->
<activity
android:name=".DetailActivity"
android:taskAffinity="com.example.detail"
android:launchMode="singleTask" />

taskAffinity 定义 Activity 的"亲和力"——当 launchModesingleTask 时,系统会在匹配的 affinity Task 中启动该 Activity。默认所有 Activity 的 affinity 为应用包名。


常见面试问题

Q1: onNewIntent 什么时候会被调用?

答案

当 Activity 已经存在且被复用时调用:

  • singleTop:Activity 在栈顶时收到新的 Intent
  • singleTask: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。适合临时页面如授权页面。

相关链接