一、引言:为什么你需要真正理解生命周期调度?
很多 Android 开发者都"会用"生命周期,但一旦遇到这些问题就容易懵:
- 为什么
onResume()有时候没执行? - 为什么切后台再回来,Activity 不是从
onCreate()开始? - 为什么在某些机型上会出现 生命周期错乱 / 丢回调?
- Fragment 生命周期为什么"跟着 Activity 但又不完全一样"?
这些问题的本质,其实都指向一个核心:
Activity 生命周期不是"自己执行"的,而是被系统调度的。
如果你不了解调度机制,就无法:
- Debug 生命周期异常问题
- 做稳定性优化(ANR / Crash)
- 做复杂场景(多窗口、冷启动优化)
👉 本文我们就从 系统调度视角,彻底搞懂 Activity 生命周期。
二、背景知识:谁在"控制"Activity?
在 Android 中,Activity 并不是你 new 出来的,而是由系统管理的。
核心参与者有三个:
1. AMS(ActivityManagerService)
👉 系统进程中的"大脑"
职责:
- 管理 Activity 栈
- 决定哪个 Activity 该显示
- 决定生命周期状态(RESUMED / PAUSED 等)
2. ActivityThread(应用进程)
👉 App 主线程的入口
职责:
- 接收 AMS 指令
- 分发生命周期回调(onCreate / onResume 等)
3. ApplicationThread(Binder 通道)
👉 AMS 和 App 之间的桥梁
scss
AMS --(Binder)--> ApplicationThread --(Handler)--> ActivityThread
📌 一句话总结:
AMS 决策,ApplicationThread 传递,ActivityThread 执行。
三、核心原理:生命周期其实是"事务驱动"的
从 Android 9(Pie)开始,生命周期调度引入了一个关键机制:
👉 ClientTransaction(客户端事务模型)
1. 生命周期 ≠ 直接调用
很多人以为:
scss
activity.onResume()
❌ 实际上不是这样调用的!
而是:
AMS → ClientTransaction → ActivityThread → 生命周期方法
2. ClientTransaction 是什么?
可以理解为:
👉 一次完整的生命周期调度"任务包"
它包含:
- 生命周期状态(Resume / Pause / Stop)
- Callback(Launch / Destroy / NewIntent 等)
3. 生命周期调度流程(核心链路)
以启动 Activity 为例:
scss
startActivity()
↓
AMS(决定启动)
↓
ClientTransaction(封装任务)
↓
ApplicationThread.scheduleTransaction()
↓
ActivityThread.H(Handler)
↓
TransactionExecutor.execute()
↓
performLaunchActivity()
↓
onCreate() / onStart() / onResume()
📌 关键结论:
生命周期不是"一个个方法调用",而是一组事务执行的结果。
四、源码解析:生命周期到底怎么被调度?
我们来看关键源码路径(基于 Android 10+)
1. AMS 发起调度
ini
clientTransaction.addCallback(LaunchActivityItem.obtain(...));
clientTransaction.setLifecycleStateRequest(
ResumeActivityItem.obtain(...)
);
👉 重点:
- Callback:做什么(如 launch)
- LifecycleState:最终状态(如 RESUMED)
2. 发送到 App 进程
ini
applicationThread.scheduleTransaction(transaction);
3. ActivityThread 接收
typescript
public void scheduleTransaction(ClientTransaction transaction) {
mH.sendMessage(...);
}
👉 切到主线程 Handler
4. TransactionExecutor 执行
scss
executeCallbacks(transaction);
executeLifecycleState(transaction);
5. 执行 launch
scss
performLaunchActivity()
最终调用:
scss
activity.onCreate()
activity.onStart()
activity.onResume()
📌 重点理解:
生命周期是"推导出来的",而不是"直接指定的"。
比如:
- 如果目标状态是 RESUMED
- 当前状态是 INITIAL
系统会自动补齐:
onCreate → onStart → onResume
五、实战示例:生命周期调度可视化
我们写一个简单 Demo,观察生命周期。
示例代码
kotlin
class MainActivity : AppCompatActivity() {
private fun log(msg: String) {
Log.d("LifeCycle", msg)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
log("onCreate")
}
override fun onStart() {
super.onStart()
log("onStart")
}
override fun onResume() {
super.onResume()
log("onResume")
}
override fun onPause() {
super.onPause()
log("onPause")
}
override fun onStop() {
super.onStop()
log("onStop")
}
override fun onDestroy() {
super.onDestroy()
log("onDestroy")
}
}
场景分析
场景1:启动 Activity
onCreate
onStart
onResume
👉 对应事务:
- LaunchActivityItem
- ResumeActivityItem
场景2:打开新 Activity
当前 Activity:
onPause → onStop
新 Activity:
onCreate → onStart → onResume
👉 AMS 做了两件事:
- Pause 当前 Activity
- Resume 新 Activity
场景3:按 Home 键
onPause → onStop
👉 目标状态:STOPPED
📌 本质:
生命周期变化 = 状态机迁移
六、常见误区(踩坑重点)
❌ 误区1:生命周期一定按顺序执行?
不一定!
比如异常场景:
- 进程被杀
- 配置变更
- 多窗口模式
👉 可能出现:
- 没有
onStop()直接onDestroy() - 或者根本没机会执行
❌ 误区2:onPause 一定比 onResume 先执行?
在多窗口模式下:
👉 多个 Activity 可以同时 RESUMED
(Android 10+ 支持)
❌ 误区3:生命周期回调一定在主线程同步执行?
✔ 在主线程
❌ 不一定是"立即执行"
因为:
它是通过 Handler 异步调度的
❌ 误区4:finish() 一定马上销毁?
scss
finish()
只是发起请求:
👉 实际销毁仍然由 AMS 调度
七、性能优化 & 最佳实践
1. 避免在 onCreate 做重操作
原因:
生命周期调度是串行的,阻塞会影响整个 UI
建议:
arduino
lifecycleScope.launch {
// 异步加载
}
2. 正确使用生命周期感知组件
推荐:
scss
lifecycle.addObserver(...)
或:
javascript
repeatOnLifecycle(Lifecycle.State.STARTED) { }
3. 避免生命周期错位问题
典型错误:
scss
onResume {
registerReceiver()
}
onPause {
unregisterReceiver()
}
👉 在多窗口下可能出问题
建议:
onStart / onStop
4. 利用 ProcessLifecycleOwner
全局生命周期监听:
csharp
ProcessLifecycleOwner.get().lifecycle
适合:
- App 前后台切换
- 统计埋点
八、总结:生命周期调度的本质
我们用一句话总结:
Activity 生命周期本质是 AMS 驱动的状态机,通过 ClientTransaction 在主线程中异步执行。
核心记住这 4 点:
- 生命周期不是你控制的,是系统调度的
- AMS 决策,ActivityThread 执行
- ClientTransaction 是调度核心
- 生命周期是状态机,而不是简单回调
最后一句
当你真正理解生命周期调度后,你会发现:
很多"玄学 Bug",其实只是你还没看懂系统的调度逻辑。