1. Compose 调试概述与工具链
刚接触 Compose 调试时,很多人会问:到底该从哪开始?坦白讲,我也迷茫过一阵子。Compose 是声明式 UI,运行时状态全靠重组——出问题了你不能像 View 系统那样直接看「某个 View 的宽高」,得换一套思路。
这一节我们不写代码,先把手里的家伙摸清楚。我习惯把调试工具分成三类:布局看诊器、日志捕手、性能探测器。它们分别对应 Layout Inspector、Logcat 和 Profile。下面一个个说。
1.1 Layout Inspector——布局的「X光机」
Layout Inspector 这东西,说白了就是把你屏幕上的 Compose 组件树拍成一张「解剖图」。你可以选某个节点,右边直接看到它的属性、修饰符、重组次数。
我项目里遇到过一个奇怪问题:Text 组件显示的文字明明对,但位置偏了 2 像素。用 Layout Inspector 一看,原来外层多了个 Modifier.padding(2.dp)——当时开发合并代码时冲突没解干净。如果没有这「X光机」,你光靠眼瞪屏幕,很难找到那 2 像素的坑。
使用技巧:在 Layout Inspector 窗口顶部的搜索框里输入 composable,可以快速过滤出所有 Compose 节点。我一般先搜「recompose」看哪些组件频繁重组。
打开方式:Tools → Layout Inspector → 选择进程 → 开始检查。嗯,这里要注意:如果你同时开了多个模拟器,进程列表会很长,建议按包名排序。
1.2 Logcat——聊天的录音笔
前面提到 Layout Inspector 是静态抓图,那 Logcat 就是动态的「聊天记录」。你可以在代码里加 Log.d("TAG", "某个重组时机"),然后看着日志流判断状态是否正确更新。
我个人习惯给每个 Compose 函数设一个唯一的 TAG,比如 "HomeScreen_Composable"。有一次排查列表项闪烁的 bug,就是靠 Logcat 里看到 LaunchedEffect 被多次调用,才发现 key 设置错了。
// 常用调试日志写法
@Composable
fun MyItem(item: Item) {
Log.d("MyItem", "重组了, item.id = ${item.id}")
Text(text = item.name)
}
顺便提一嘴:Logcat 的过滤栏里可以用 package:mine 只看当前应用日志,再用 tag:MyItem 缩小范围,这俩组合是我最常用的。
踩坑提醒:我曾经在生产包上忘记删除调试日志,导致 Logcat 疯狂输出,拖慢 UI 线程。建议用 BuildConfig.DEBUG 包一下日志代码,release 时自动去掉。
1.3 Profile——性能的侦探器
Profile 工具可以记录 CPU、内存、网络、以及 Compose 特有的 重组次数 和 Compose 阶段耗时。我个人最常用的是「Record & Profile」,运行一小段操作,然后看火焰图。
你知道 Compose 的 UI 构建分三个阶段吗?组合 → 布局 → 绘制。如果在火焰图里看到「Layout」阶段特别长,多半是某个 Modifier 或 Layout 自定测量搞了复杂计算。我优化过一个卡片滑动卡顿的问题,就是靠 Profile 定位到 Modifier.shadow 在每次重组都重新计算阴影路径——换成预置的 Elevation 直接降了 30% 耗时。
关键指标:关注 Recomposition count 是否超过预期。一个典型的列表项如果在滑动时每帧都重组,那肯定有问题。正常情况应该只有需要更新的项才重组。
打开方式:View → Tool Windows → Profiler → 选择设备 → 选择 Compose 选项卡(如果有)或直接看 CPU。
1.4 一张图串起三个工具
下面这张图是 Compose 调试工具链的协作逻辑:发现 bug → 用哪个工具 → 怎么定位。我个人觉得这张图能帮你形成「调试直觉」。
1.5 一张比较表帮你快速决策
| 工具 | 擅长场景 | 不擅长的场景 | 我常用的启动方式 |
|---|---|---|---|
| Layout Inspector | 组件层级、修饰符、属性值 | 无法捕捉动画过程中的中间态 | Tools → Layout Inspector |
| Logcat | 状态变化、事件触发顺序 | 定位性能瓶颈(缺少时间戳分析) | 底部 Logcat 窗口直接查看 |
| Profiler | 重组次数、阶段耗时、内存泄漏 | 不能直接看到 UI 的视觉表现 | View → Tool Windows → Profiler |
1.6 小结:先有工具思维,再下手调试
你看,这三个工具其实覆盖了 Compose 调试的三种典型链路:看结构 → 看日志 → 看性能。我个人经验是,先判断你的问题属于哪一类,然后直奔对应的工具。如果交叉验证后依然找不出原因,就把三个工具的结果放在一块对比——这招帮我至少解决过 3 个线上疑难杂症。