13. 功耗测量工具:Power Monitor使用、BatteryStats分析、Perfetto抓取功耗数据

做相机功耗优化,最怕什么?

怕你改了一堆代码,自我感觉良好,结果一测——功耗不降反升。

所以这一章,咱们聊聊怎么用工具把功耗「看」清楚。我个人习惯把这三种工具比作三把尺子:Power Monitor 是游标卡尺,BatteryStats 是卷尺,Perfetto 是CT扫描仪。各有各的用处,缺一不可。

核心观点:没有测量就没有优化。你连功耗花在哪都不知道,谈何优化?

功耗测量工具三件套 Power Monitor 硬件级电流测量 BatteryStats 软件级电量统计 Perfetto 全链路时间线追踪 实时电流曲线 · 瞬时功耗 dumpsys batterystats · 耗电排行 systrace升级版 · 线程/频率/唤醒 使用场景建议 硬件调试 → Power Monitor | 日常监控 → BatteryStats | 深度分析 → Perfetto

13.1 Power Monitor:看电流的「显微镜」

Power Monitor 这东西,说白了就是一块硬件板子,串联在手机电池和主板之间。它能实时采集电流数据,精度能到毫安级别。

我记得第一次用 Power Monitor 时,发现相机预览阶段的电流居然有 800mA。当时我就懵了——这比正常值高了快一倍。后来一查,是某个 sensor 的供电没关,一直在空转。

我的习惯:每次改完相机相关的代码,都会用 Power Monitor 跑一遍「预览→拍照→录像→退出」的完整流程。看电流曲线有没有异常凸起。

Power Monitor 的核心用法:

  • 连接方式:取下手机电池,用 Power Monitor 的夹子夹住电池触点。注意正负极别接反,我见过有人接反直接把板子烧了。
  • 采样率设置:一般设 1000Hz 就够用。太高了数据量太大,太低了抓不到瞬态尖峰。
  • 关键指标:平均电流、峰值电流、待机底电流。相机场景下,重点关注「预览→拍照」切换时的电流跳变。

警告:Power Monitor 测的是整机电流。如果你想知道「相机模块单独吃了多少电」,需要配合其他手段做差分。我曾经踩过这个坑——以为优化了相机,结果省的是屏幕的功耗。

13.2 BatteryStats:系统自带的「记账本」

BatteryStats 是 Android 系统内置的耗电统计服务。它不测瞬时电流,而是记录「谁在什么时间段消耗了多少电量」。说白了,就是个软件层面的记账本。

我经常在开发机上跑这个命令:

adb shell dumpsys batterystats --reset  # 先清零
# 然后跑你的相机测试场景
adb shell dumpsys batterystats --charged > battery_stats.txt

打开生成的文本,你会看到类似这样的信息:

Estimated power use (mAh):
  Camera: 120.0
  Screen: 85.0
  Wifi: 23.0
  ...

嗯,这里要注意:BatteryStats 的估算值不一定准,但它能告诉你相对趋势。比如你改了一版代码,Camera 的耗电从 120mAh 降到了 90mAh,那说明优化有效。

避坑指南:我曾经发现 BatteryStats 里 Camera 耗电异常高,但 Power Monitor 测出来整机电流正常。后来才发现,是某个第三方应用一直在后台调相机权限,被系统算到了 Camera 头上。所以,BatteryStats 的数据要结合其他工具交叉验证

BatteryStats 的常用字段:

字段 含义 相机场景关注点
Estimated power use 各模块估算耗电 Camera 占比是否合理
Uid u0aXXX 每个应用的耗电明细 相机进程的 CPU/GPU 唤醒次数
Kernel wake locks 内核唤醒锁 相机 sensor 是否异常持锁
Network 网络流量耗电 相机上传/下载是否频繁

13.3 Perfetto:全链路「时间旅行」

Perfetto 是 Google 推出的新一代性能追踪工具,可以看作是 systrace 的升级版。它能记录 CPU 频率、线程调度、Binder 调用、电源状态等几百种事件,时间精度到微秒级。

我个人觉得,Perfetto 是相机功耗优化的终极武器。为什么?因为相机场景涉及太多模块——ISP、DSP、GPU、CPU、DDR……它们之间的协作关系,只有 Perfetto 能看得清。

抓取 Perfetto 数据的命令:

# 抓取 10 秒数据,包含相机相关 trace
adb shell perfetto \
  -c - --txt \
  -o /data/misc/perfetto-traces/trace.perfetto-trace \
  <<< '{
    "buffers": [{"size_kb": 65536}],
    "data_sources": [
      {"config": {"name": "linux.ftrace", "target_buffer": 0}},
      {"config": {"name": "linux.process_stats", "target_buffer": 0}},
      {"config": {"name": "android.power", "target_buffer": 0}}
    ],
    "duration_ms": 10000
  }'

# 拉取到本地
adb pull /data/misc/perfetto-traces/trace.perfetto-trace .

然后打开 ui.perfetto.dev,把 trace 文件拖进去。你会看到一条条彩色的时间线。

我的经验:在 Perfetto 里,重点关注这几个信号:

  • CPU 频率:相机预览时,CPU 是否频繁跳频?如果是,说明负载不稳定。
  • GPU 渲染:每一帧的渲染时长是否超过 16ms?超了就会掉帧,掉帧往往伴随功耗飙升。
  • wake lock:相机进程是否长时间持有唤醒锁?这会导致系统无法进入深度睡眠。
  • Binder 调用:相机 HAL 和 framework 之间的通信是否频繁?每次 Binder 调用都有开销。

举个例子。有一次我发现相机预览时功耗偏高,Perfetto 一看,发现 CPU 的小核在 1.2GHz 和大核在 1.8GHz 之间来回跳。频率切换本身就有功耗开销。后来我把相机线程绑到了中核上,频率稳定在 1.5GHz,功耗反而降了 15%。

注意:Perfetto 的数据量很大。抓 10 秒可能就有几十 MB。不要在生产环境长时间抓取,否则 trace 本身就会影响功耗。我一般只抓 5-10 秒的关键场景。

13.4 三把尺子怎么配合用?

你可能会问:这三个工具,到底先用哪个?

我的建议是:

  1. 先用 BatteryStats 做粗筛。跑一遍测试场景,看看 Camera 的耗电占比是否异常。如果正常,那可能问题不在相机。
  2. 再用 Power Monitor 看电流曲线。找到功耗异常的「时间窗口」。比如拍照瞬间电流飙升到 2A,那问题就出在拍照流程里。
  3. 最后用 Perfetto 做精确定位。在异常时间窗口里,看 CPU/GPU/ISP 到底在干什么。是某个线程在空转?还是某个驱动没释放资源?

这套流程,我在好几个项目里都用过。每次都能快速定位到问题根因。说白了,工具是死的,但思路是活的。

总结一句话:Power Monitor 告诉你「功耗高不高」,BatteryStats 告诉你「谁吃的多」,Perfetto 告诉你「为什么吃得多」。三件套齐了,功耗优化才能做到心中有数。

好了,这一章就聊到这。工具讲完了,下一章咱们开始讲具体的优化手段——从代码层面,怎么把相机的功耗一点一点抠下来。


公众号:蓝海资料掘金营,微信deep3321