Activity 是 Android 四大组件中最直观、最常接触的组件,也是应用架构的核心载体。每一个界面都对应一个 Activity 实例,其背后涉及 ActivityThread 的消息驱动、Instrumentation 的测试/监控层、AMS/ATMS 的远程调度以及 Window 的创建与管理。本文从源码出发,深入剖析 Activity 的生命周期状态机、Configuration 变化处理、launchMode 对 Task 的影响以及跨进程回调机制。
一、Activity 的进程归属:ActivityThread 与主线程
1.1 ActivityThread.main——应用进程的起点
每个 Android 应用进程本质上是由 Zygote fork 出来的 Java 虚拟机进程。进程的 Java 入口是 ActivityThread.main:
// frameworks/base/core/java/android/app/ActivityThread.java |
这里的核心要点:
Looper.prepareMainLooper()在主线程创建了一个 Looper 和 MessageQueue;Looper.loop()进入死循环,不断消费 MessageQueue 中的消息;- 所有 Activity 的生命周期回调(onCreate、onStart、onResume 等)都是通过主线程的 Handler(mH)分发执行的。
为什么 Looper.loop() 是死循环但不会导致 ANR?
ANR 的触发条件是在规定时间内没有响应 Input 事件或特定 Message。Looper.loop() 本身只是一个消息泵——当没有消息时,线程在 Linux pipe/epoll 上阻塞等待(通过 nativePollOnce),不消耗 CPU。ANR 是在消息处理耗时过长时触发的,而非”没有消息”时触发。
1.2 mH——ActivityThread 的内部 Handler
// frameworks/base/core/java/android/app/ActivityThread.java |
注意:BIND_APPLICATION 消息的优先级最高(排在第一个处理分支中),它负责初始化 Application 和 ContentProvider。这也是 ContentProvider.onCreate 在 Application.onCreate 之前执行的原因——Provider 在 BIND_APPLICATION 消息处理过程中被初始化。
二、Activity 生命周期状态机
2.1 生命周期状态定义
在 AOSP 中,Activity 的生命周期被定义为一组明确的回调方法,但在 ATMS 内部,使用 ActivityRecord.State 枚举管理状态迁移:
// frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java |
过渡态(PAUSING、STOPPING、DESTROYING)的存在是为了处理异步的跨进程生命周期回调——system_server 发出 pause/stop/destroy 指令后,需要等待 App 进程的确认才能进入最终状态。如果 App 进程在过渡态卡住(如主线程阻塞),会导致 ANR。
2.2 生命周期状态迁移图
┌─────────────┐ |
2.3 Instrumentation——生命周期调用的中介层
Instrumentation 是 Activity 生命周期回调的中间层。所有 AMS/ATMS 发起的生命周期调用都经过 Instrumentation:
// frameworks/base/core/java/android/app/Instrumentation.java |
Instrumentation 的存在使得 Android 测试框架(如 Espresso、Robolectric)可以拦截和监控所有生命周期回调。例如:
// Espresso 的 ActivityMonitor 通过 Hook ActivityThread 的 mInstrumentation |
2.4 handleLaunchActivity——Activity 启动的核心
// frameworks/base/core/java/android/app/ActivityThread.java |
三、Configuration 变化处理
3.1 两种处理模式
当设备配置发生变化(如屏幕旋转、语言切换、夜间模式切换等)时,Activity 有两种响应模式:
模式 1:重建 Activity(默认行为)
系统销毁 Activity 再重新创建。完整流程:onPause → onStop → onDestroy → onCreate → onStart → onResume。
模式 2:onConfigurationChanged 回调
当 Activity 在 AndroidManifest 中声明 android:configChanges 时,系统不销毁 Activity,而是直接回调 onConfigurationChanged。
3.2 AMS/ATMS 端的处理
// frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java |
配置变更类型定义在 android.content.res.Configuration 和 android.content.pm.ActivityInfo 中:
CONFIG_ORIENTATION = 0x0002CONFIG_SCREEN_SIZE = 0x0400CONFIG_LOCALE = 0x0004CONFIG_KEYBOARD = 0x0010CONFIG_UI_MODE = 0x0200(夜间模式)CONFIG_SCREEN_LAYOUT = 0x0100CONFIG_FONT_SCALE = 0x40000000
3.3 onSaveInstanceState 与恢复
在 Activity 因配置变化被销毁前,系统调用 onSaveInstanceState(Bundle outState) 保存状态:
// frameworks/base/core/java/android/app/Activity.java |
saveHierarchyState 内部遍历 View 树,为每个 View 调用 dispatchSaveInstanceState() 保存状态(如 EditText 的当前文本和光标位置)。
四、launchMode 对 Task 管理的影响
4.1 四种 launchMode
launchMode 在 AndroidManifest 的 <activity> 标签中声明,或在 Intent 中通过 flags 覆盖。
standard(默认):每次启动都创建新实例,放入调用者所在的 Task。
singleTop:如果目标 Activity 已在栈顶,则复用,调用 onNewIntent();否则新建实例。
singleTask:系统中只能有一个实例。如果已存在但在不同 Task,则将该 Task 移到前台,并清除其上的所有 Activity(或调用 onNewIntent,取决于 FLAG_ACTIVITY_CLEAR_TOP)。
singleInstance:与 singleTask 类似,但该 Activity 独占一个 Task,此 Task 不允许其他 Activity 进入。
4.2 源码中的处理(ActivityStarter)
// frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java |
4.3 Intent Flags 与 launchMode 的交互
Intent flags 可以覆盖 launchMode 行为:
FLAG_ACTIVITY_NEW_TASK:效果等同于 singleTaskFLAG_ACTIVITY_CLEAR_TOP:清除目标 Activity 之上的所有 ActivityFLAG_ACTIVITY_SINGLE_TOP:效果等同于 singleTopFLAG_ACTIVITY_CLEAR_TASK:启动前清除整个 Task(常与 FLAG_ACTIVITY_NEW_TASK 组合)
当 Intent flag 与 Manifest launchMode 冲突时,ActivityStarter 优先使用 Intent flag。
五、ActivityClientRecord 与跨进程回调
5.1 ActivityClientRecord 的数据结构
App 进程中的每个 Activity 都对应一个 ActivityClientRecord,它包含 Activity 实例及其必要的上下文信息:
// frameworks/base/core/java/android/app/ActivityThread.java |
5.2 ApplicationThread——跨进程 Binder 回调
ApplicationThread 是 ActivityThread 的内部类,继承自 IApplicationThread.Stub,是 system_server 向 App 进程发送生命周期指令的 Binder 接口。
Android 10 引入 ClientTransaction 和 ClientLifecycleManager 统一了生命周期事务的编排:
// frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java |
5.3 ClientTransaction 中的生命周期回调链
一个 ClientTransaction 包含多个 ClientTransactionItem(生命周期回调项),例如:
// 启动 Activity 的典型 transaction |
LifecycleStateRequest 的含义:它声明了事务执行完成后 Activity 应达到的最终状态。例如,ResumeActivityItem 表示 Activity 最终应为 RESUMED。App 进程收到后,执行所有 callbacks(创建 Activity、onCreate、onStart),最后通过 executeLifecycleState 将 Activity 过渡到目标状态(onResume)。
六、核心面试题
Q1:Activity 的 onNewIntent 在什么场景下被调用?其调用时机是怎样的?
onNewIntent 在 Activity 处于 singleTop(栈顶复用)、singleTask 或 singleInstance 模式时被调用。调用时机通常是:onPause → onNewIntent → onResume(如果 Activity 已经在前台)。如果是后台 Activity 被新 Intent 唤起,则生命周期顺序是:onNewIntent → onRestart → onStart → onResume。在 onNewIntent 中应调用 setIntent(intent) 更新内部存储的 Intent。
Q2:当一个 Activity 被部分遮挡(比如弹出 Dialog),它的生命周期如何变化?为什么?
弹出 Dialog 是同一个应用进程内的操作,不触发 AMS 级别的生命周期回调。Dialog 本质上是 Activity Window 之上的一个子窗口(type = TYPE_APPLICATION),Activity 仍然处于 RESUMED 状态。但如果启动一个半透明的 Activity 覆盖在上面,下层 Activity 执行 onPause()(停止交互但可见),进入 PAUSED 状态。Android 10+ 半透明 Activity 不再允许 resumedOnTop。
Q3:Activity 的重建机制中,onRetainNonConfigurationInstance 和 ViewModel 的关系是什么?
onRetainNonConfigurationInstance() 是 Android 早期提供的跨配置变更保留对象机制。在 Android Architecture Components 推出后,ViewModel 成为推荐的方式,内部正是基于此机制实现的——ComponentActivity 的 getLastNonConfigurationInstance() 保存着 ViewModelStore,在 Activity 重建时恢复 ViewModel 实例。
Q4:ActivityThread 的 main 方法中为什么需要 Looper.loop() 死循环?
Android 应用的主线程是一个事件驱动模型。所有 UI 操作、生命周期回调、触摸事件分发都需要在主线程中串行处理。Looper.loop() 提供了这个串行化的事件处理循环。如果退出循环,主线程就没有办法再接收和处理任何消息——所有 UI 操作都会失败,进程实际已处于”假死”状态。
Q5:为何 onStart 和 onResume 之间需要区分?两者状态的区别是什么?
onStart 标志 Activity 变为可见(Activity 进入 STARTED 状态),onResume 标志 Activity 变为前台可交互(进入 RESUMED 状态)。区别场景:当启动一个半透明 Activity 时,下层 Activity 调用 onPause(进入 PAUSED,停止交互但可见),当半透明 Activity 关闭时,下层 Activity 调用 onResume 恢复交互——但不会再次调用 onStart/onStop(因为始终可见)。
七、Activity 的 Window 创建与管理
7.1 activity.attach() 中的 Window 初始化
在 performLaunchActivity 中调用 activity.attach(),这是 Activity 与其 Window 建立关系的时刻:
// frameworks/base/core/java/android/app/Activity.java |
7.2 Activity.setContentView 的完整链路
// Activity.java |
7.3 Activity 与 Fragment 生命周期同步
Fragment 的生命周期由 FragmentManager 管理,但与 Activity 生命周期紧密耦合:
Activity.onCreate → FragmentManager.dispatchCreate() |
对于 Fragment 的视图生命周期(onCreateView → onDestroyView),FragmentManager 在 Fragment 切换时独立管理,与 Activity 的生命周期不完全一致。例如:Fragment A 替换为 Fragment B 时,A 调用 onDestroyView(视图销毁),但 A 的 onDestroy 只在 Activity destroy 时才调用。
八、Activity 的过渡与动画
8.1 Activity Transition(共享元素过渡)
Android 5.0 引入了 Activity Transition API,支持共享元素动画:
// 启动 Activity 时指定共享元素 |
AMS 端处理:在 ActivityStarter 中,检查传入的 Bundle 中是否有 android:transitionName 映射。如果有,在 start 和 finish 时播放过渡动画。
8.2 overridePendingTransition
// 自定义 Activity 切换动画 |
这个方法必须在 startActivity() 或 finish() 之后立即调用。它在 Android 内部通过 ActivityRecord 的动画状态控制。
AOSP 核心路径参考:
frameworks/base/core/java/android/app/ActivityThread.javaframeworks/base/core/java/android/app/Activity.javaframeworks/base/core/java/android/app/Instrumentation.javaframeworks/base/core/java/android/app/servertransaction/ClientTransaction.javaframeworks/base/services/core/java/com/android/server/wm/ActivityStarter.javaframeworks/base/services/core/java/com/android/server/wm/ActivityRecord.javaframeworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java






