compose 重组流程

将 Compose 的重组(Recomposition)流程说清楚,可以将其拆解为:触发、执行、优化、挂载四个阶段。

可以把它想象成:「数据变化」驱动「代码重跑」,最终「智能刷新」UI 的过程。


1. 触发阶段(监听与失效)

重组的起点永远是 State(状态)。

  • 读取追踪:当第一次运行一个 Composable 函数时,Compose 框架会记录下:哪个函数读取了哪个 State 对象。
  • 状态变化:当修改 mutableStateOf 的值时。
  • 标记失效:Compose 立即将所有读取了该状态的 Composable 函数标记为 Invalid(失效)。它并不会立刻刷新,而是等待下一个垂直同步信号(Vsync)到来时统一处理。

2. 执行阶段(Composition / 代码重跑)

当系统准备好刷新时,它会重新运行那些被标记为"失效"的函数。

  • 重新执行:函数带着最新的数据再次运行,生成一棵新的描述树(UI 蓝图)。
  • 局部运行:Compose 非常聪明,如果函数 A 的状态没变,它只会重新运行函数 B。
  • 位置记忆:在这个过程中,remember 起到了关键作用。它像是一个"存档点",让函数重新运行到这一行时,能拿回之前存的值,而不是重置。

3. 优化阶段(Skipping / 智能跳过)

这是 Compose 性能强大的核心:并不是所有被调用的函数都会重跑。

  • 参数对比:在重新运行一个函数前,Compose 会对比它的输入参数。
  • 判定跳过:如果参数是稳定的(比如 String、Int 或 data class),且值没有变化,Compose 会直接 Skip(跳过) 这个函数。
  • 为什么需要 remember?:如果不给 List 加 remember,每次重组它都是一个"新地址",Compose 就会认为参数变了,无法触发跳过逻辑。

4. 挂载阶段(Applying Changes / 差异对比)

生成了新的"蓝图"后,Compose 不会把旧 UI 全部拆掉重建,而是做 Diff(差异对比)。

  • 找出差异:对比旧树和新树。比如:发现只有左边 Text 的颜色变了,或者中间多了一个 Button。
  • 最小化更新:只对发生变化的底层原生 UI(LayoutNode)进行修改。
  • 绘制:最终触发 Android 系统的 Draw 流程,用户看到界面更新。

5. 重组的三个重要特性(开发者必知)

  1. 重组是乐观的:Compose 假设重组很快就能跑完。如果重组还没跑完,数据又变了,Compose 会直接掐断当前的重组,重新开始新的一轮。
  2. 重组是并发的:Compose 框架可以在后台线程处理重组逻辑(虽目前主线程较多),所以严禁在函数体里写 Side Effect(副作用),比如修改全局变量。
  3. 顺序不确定:不同的 Composable 函数可能以任意顺序运行,甚至并行运行。

总结

重组流程图:

State 改变 →\rightarrow→ 标记函数失效 →\rightarrow→ 重新运行函数(尝试跳过未变部分) →\rightarrow→ 生成新 UI 树 →\rightarrow→ Diff 差异 →\rightarrow→ 更新屏幕。

在开发 RankGroupScreen 或 AccountScreen 时频繁使用 remember,本质上就是在给 Compose 提供"跳过"的理由,从而通过优化"执行阶段"来让应用更流畅。

如果想看哪些函数被跳过了,哪些在重复跑,可以使用 Android Studio 的 Layout Inspector,它会用数字标出每个组件重组的次数。

想了解如何通过 Stable 注解 来进一步强制让 Compose 跳过某些不必要的重组吗?

相关推荐
stevenzqzq1 天前
Compose 中 collectAsStateWithLifecycle 与重组的核心关系解析
compose
stevenzqzq7 天前
compose中 rememberUpdatedState和remember的区别
compose
stevenzqzq7 天前
compose中 contentPadding和Modifier.padding的区别
compose
stevenzqzq10 天前
Android Navigation 组件页面跳转方法说明
android·compose
zh_xuan14 天前
Android compose 可见性动画未执行问题修复
android·compose
hnlgzb15 天前
请详细解释一下MVVM这个设计模型
android·kotlin·android jetpack·compose
hnlgzb17 天前
目前编写安卓app的话有哪几种设计模式?
android·设计模式·kotlin·android jetpack·compose
zh_xuan20 天前
Android compose Navigation 页面导航
android·compose
stevenzqzq23 天前
Kotlin 进阶指南:中缀函数 (Infix Function)
android·kotlin·compose