Activity 生命周期是如何被调度的?(从源码到实战全链路拆解)

一、引言:为什么你需要真正理解生命周期调度?

很多 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 点:

  1. 生命周期不是你控制的,是系统调度的
  2. AMS 决策,ActivityThread 执行
  3. ClientTransaction 是调度核心
  4. 生命周期是状态机,而不是简单回调

最后一句

当你真正理解生命周期调度后,你会发现:

很多"玄学 Bug",其实只是你还没看懂系统的调度逻辑。

相关推荐
sp42a2 小时前
将 NativeScript 项目升级到 Android API 35 级别
android·nativescript
tangweiguo030519872 小时前
iOS vs Android 开发对照手册
android·ios
用户69371750013842 小时前
跟你唠唠!A2A协议来了,谁能拿下下一代手机系统的主动权?
android·前端·人工智能
用户69371750013842 小时前
微信悄悄搞大事!原生智能助手秘密研发,2026年改变亿人使用习惯
android·后端·微信小程序
轩情吖2 小时前
MySQL之表的增删查改
android·开发语言·c++·后端·mysql·adb·
robotx2 小时前
安卓15开机动画结束流程简单分析
android
XiaoLeisj2 小时前
Android 模块化与组件化工程实战:从子模块库化、Gradle 配置统一到 ARouter 解耦跨模块页面通信与 Fragment 解耦集成
android·gradle·模块化·arouter
JMchen1233 小时前
高级渲染技术:OpenGL ES在自定义View中的应用
android·性能优化·3d渲染·opengl es·自定义view·glsurfaceview·shader编程
鹧鸪晏3 小时前
搞懂 kotlin 泛型 out 和 in 关键字
android·kotlin