Activity 切换、配置变更与销毁如何保持一致
Activity 切换、配置变更与销毁如何保持一致
Activity 切换、配置变更和销毁都同时涉及两份状态:system_server 中的 ActivityRecord 状态, 以及应用进程里实际执行的生命周期回调。系统先决定目标状态,再通过客户端事务驱动应用; 两边短时间内不完全同步是正常过渡,长期不收敛才是故障。
先区分服务端状态与客户端回调
| 常见误解 | 正确理解 |
|---|---|
| 销毁 Activity 就是移除服务端记录 | 销毁先推进 State(FINISHING → DESTROYING → DESTROYED),再发事务给客户端 |
| 配置变更一定会重建 Activity | 只有系统无法通过 onConfigurationChanged 适配时才 relaunch |
切换、配置、销毁都是“先改服务端状态,再通知客户端执行”,两边的时序由客户端事务保证。
三条主链
逐步解释:
- ① 切换:
Task.resumeTopActivityUncheckedLocked()(Task.java:5103)决定恢复栈顶,旧 Activity 先暂停。 - ② 配置变更:
ActivityRecord.ensureActivityConfiguration()(ActivityRecord.java:8019)判断是否需要 relaunch。 - ③ 销毁:
destroyIfPossible()(ActivityRecord.java:3966)先setState(FINISHING, ...)(3967 行),再发DestroyActivityItem事务。
服务端状态推进
所有状态变化都走 setState(State, reason)(ActivityRecord.java:5929)。销毁路径的典型顺序:
FINISHING → DESTROYING → DESTROYED客户端收到 DestroyActivityItem(servertransaction/DestroyActivityItem.java:33)后在主线程执行 onDestroy。配置变更使用 ConfigurationChangeItem(ConfigurationChangeItem.java:34)或 relaunch。
客户端事务项
| 场景 | 客户端事务项 | 行号 |
|---|---|---|
| 暂停 | PauseActivityItem | PauseActivityItem.java:34 |
| 恢复 | ResumeActivityItem | ResumeActivityItem.java:35 |
| 配置变更 | ConfigurationChangeItem | ConfigurationChangeItem.java:34 |
| 销毁 | DestroyActivityItem | DestroyActivityItem.java:33 |
这些项与 LaunchActivityItem 一样,都由 ClientLifecycleManager 打包下发;事务执行主链见 ClientTransaction 生命周期事务。
源码证据
阅读目标:确认销毁从状态推进开始。
正文指针:ActivityRecord.java:3966-3967;Task.java:5103。
// ActivityRecord.java:3966-3967
boolean destroyIfPossible(String reason) {
setState(FINISHING, "destroyIfPossible");这段代码证明: 销毁先推进服务端状态,客户端回调由后续事务驱动,不是“删记录”一步完成。
与 WMS 的衔接
Activity 切换时的窗口动画与 Transition 由 WMS/Shell 编排,见动画、切换与窗口移除如何保持一致。本章负责逻辑状态,视觉呈现归 WMS 系列。
源码入口
Activity 服务端状态收敛后,窗口和 Surface 的移除还要继续推进,见 窗口移除与 Transition。
源码基准:android-14.0.0_r75。
以下文件默认位于 frameworks/base/,表中省略该前缀:
| 文件 | 关键位置 | 作用 |
|---|---|---|
services/core/java/com/android/server/wm/Task.java | 5103 行 resumeTopActivityUncheckedLocked(...) | 恢复栈顶 |
services/core/java/com/android/server/wm/ActivityRecord.java | 3966 行 destroyIfPossible(...);3967 行 setState(FINISHING, ...);4088-4105 行 destroyActivityLocked;8019 行 ensureActivityConfiguration();6556 行 schedulePauseTimeout() | 销毁与配置 |
core/java/android/app/servertransaction/ | PauseActivityItem.java:34;ResumeActivityItem.java:35;ConfigurationChangeItem.java:34;DestroyActivityItem.java:33 | 客户端事务项 |