1. 调试概述与 Compose 调试基础

说起调试,很多人的第一反应是:“Bug 来了,怎么办?” 其实在 Compose 里,调试不只是找 Bug,更是理解 UI 如何被渲染、重组、重绘。我个人的习惯是,拿到一个运行卡顿或布局异常的问题,先用工具跑一遍基础诊断,而不是直接看代码。咱们一步步来梳理。

1.1 为什么调试在 Compose 中尤为重要

Compose 是声明式 UI 框架,它把布局、绘制、动画都封装在重组(Recomposition)的周期里。一旦出现性能问题,往往不是单个方法慢,而是整个重组链条出了问题。举个例子:一个状态改变可能触发整个树的重组,这在传统 View 系统里是极少见的。

我在项目里遇到过这样的情况:一个简单的列表滚动,因为某个 ViewModel 的 liveData 频繁发射,导致整个 LazyColumn 的 Item 全部重组。用传统的 Log 去排查根本看不出哪里慢,直到我打开了 Layout Inspector 的 Compose 面板——嗯,真相一目了然。

核心观点:Compose 调试的关键在于“观测重组”,而不是观察绘制。

1.2 调试工具链全景图

为了理清思路,我把常用的调试手段和工具画了一张结构图,方便对照。

Compose 调试工具链结构 问题来源(性能/布局/行为) 代码层工具 Compiler Metrics 布局层工具 Layout Inspector 运行时工具 Recomposition Counts decompile + 字节码 3D 视图 + 组件树 监控面板(onGloballyPositioned) 💡 调试切入点(按场景选择) • 布局异常 → Layout Inspector/3D 视图 • 性能卡顿 → Compiler Metrics + Recomposition Counts • 状态不更新 → 检查重组链 + SideEffect
个人建议:不要一上来就刷 Log,先根据现象选工具再定位,效率差很多。

1.3 基础调试手段速查表

调试目标 推荐工具/手段 关键指标
检查重组次数 Layout Inspector + Compose 面板 Recomposition count
分析编译产物
-P composeCompilerMetrics=true
Stability(稳定性)
定位 Layout 溢出 Layout Inspector 3D 模式 边界矩形/溢出标记
性能火焰图 Perfetto + Compose 跟踪 Compose 阶段耗时

1.4 快速上手:开启 Compose 调试模式

先别急着一头扎进代码,你首先需要确保调试面板是活的。很多团队用了 Compose 但不知道 Android Studio 里有个专门的 Compose 调试入口。

// 在 build.gradle 中确保依赖
debugImplementation "androidx.compose.ui:ui-tooling:1.7.x"
debugImplementation "androidx.compose.ui:ui-test-manifest:1.7.x"

// 然后运行 app,在 Android Studio 中点击
// View → Tool Windows → Layout Inspector (新版叫 Layout Inspector with Compose)

打开后你会看到一个 3D 视角的组件树。还记得我前面提到的那个列表重组问题吗?就是在这棵树上看到了 Item 的 Recomposition Count 一直在增长,而其他 Item 的数据根本没变——当场破案。

曾经踩过的坑:我在发布版的 APK 上用 Layout Inspector,发现打不开——因为 release 构建默认没有 ui-tooling 库。切记只加在 debugImplementation 里。

1.5 理解 Compose 调试的核心概念

玩转调试工具之前,有几个概念你得心里有数。我整理成了一段简短的口诀:

  • 重组(Recomposition):状态变化后,Compose 重新执行 @Composable 函数。调试时你看的就是它。
  • 跳过(Skipping):如果参数没变化并且函数是稳定的,Compose 会跳过重组——这是性能优化的风向标。
  • 稳定(Stability):一个数据类是否被标记为 stable 影响能否跳过。你可以在 Compiler Metrics 里查看。
  • 副作用(SideEffect):LaunchedEffect、DisposableEffect、remember 这些都是调试的“警戒区”,容易导致意外触发。
一句话总结:调试 Compose 就是观察“谁重组了”、“为什么重组”、“能不能不重组”。

1.6 我的调试前检查清单

在正式开始之前,我一般会花 3 分钟跑一遍下面的清单,少走很多弯路:

  1. 确认 Android Studio 版本 >= Hedgehog(新版工具链支持更好)
  2. 确认 debug build 包含 ui-tooling 和 ui-test-manifest
  3. 打开 Layout Inspector 并切换到 Compose 模式(别选错)
  4. 运行目标页面,点击几遍,看 Recomposition Counts 变化
  5. 如果卡顿严重,顺便记录一下 Compose 阶段的耗时(用 Perfetto)

嗯,这套流程救了我不下十次,你也可以试试。

1.7 小结

调试不是抓瞎,而是有策略地使用工具。Compose 提供的 Layout Inspector、Compiler Metrics、重组计数器都是你的眼睛。把它们组合起来,大多数性能或布局问题在半小时内就能定位。记住一个原则:先观测后改代码,别凭感觉乱加 remember。后面章节我们会深入每一个工具的实战用法——但今天先把基础打牢,足够了。