14、电源管理调试:dumpsys battery、wakelock分析、功耗曲线、Doze模式
电源管理,说白了就是让手机更省电。但省电和流畅之间,往往需要做很多权衡。我调试过不少功耗问题,有些是硬件底层的锅,但更多时候,是软件层面的“锁”没用好,导致系统睡不下去。
这一章,我们就来聊聊电源调试的几个核心工具和概念。你掌握了这些,基本就能定位大部分异常耗电问题了。
14.1 先看电池状态:dumpsys battery
我最常用的第一招,就是敲 adb shell dumpsys battery。它能告诉你当前电池的实时状态,是充电还是放电,电量多少,温度如何。
adb shell dumpsys battery
Current Battery Service state:
AC powered: false
USB powered: true
Wireless powered: false
Max charging current: 500000
Max charging voltage: 5000000
Charge counter: 2450000
status: 2
health: 2
present: true
level: 65
scale: 100
voltage: 3875
temperature: 310
technology: Li-ion
这里有几个关键字段:
- level:当前电量百分比。65 就是 65%。
- status:充电状态。2 表示正在充电,1 是未充电,5 是充满。
- temperature:温度,单位是 0.1 摄氏度。310 就是 31.0°C。
- voltage:电池电压,单位毫伏。
dumpsys battery set level 5 强制把电量设为 5%。测试完记得 dumpsys battery reset 恢复。
14.2 Wakelock 分析:谁在阻止系统休眠?
系统想睡,但有些 App 或服务不肯放手。它们通过申请 WakeLock 来阻止 CPU 进入深度睡眠。这就是耗电的元凶之一。
查看当前 WakeLock 持有情况:
adb shell dumpsys power | grep -A 10 "Wake Locks"
Wake Locks: size=3
PARTIAL_WAKE_LOCK 'AudioMix' (uid=1000, pid=1234, ws=null)
PARTIAL_WAKE_LOCK 'LocationManagerService' (uid=1000, pid=5678, ws=null)
SCREEN_DIM_WAKE_LOCK 'WindowManager' (uid=1000, pid=9012, ws=null)
每个 WakeLock 都有名字、持有者 UID 和 PID。你可以根据名字判断是哪个模块在搞鬼。
我个人习惯,先看 PARTIAL_WAKE_LOCK,因为它会让 CPU 保持运行,屏幕却可以关掉。这种锁如果长时间不释放,耗电会非常明显。
dumpsys power 抓到后,直接反馈给厂商修复。
14.3 功耗曲线:用 BatteryHistorian 看全局
光看静态的 WakeLock 还不够。你需要知道 时间轴上的功耗变化。Google 提供了 BatteryHistorian 工具,可以把系统日志转成可视化的 HTML 报告。
生成步骤:
- 抓取 bugreport:
adb bugreport bugreport.zip - 上传到 https://bathist.ef.lc/ 或本地部署 BatteryHistorian
- 查看各条曲线:CPU 频率、网络活动、WakeLock 持有时间、屏幕状态等
你会看到类似这样的时间线:
从这张图里,你能直观看到:屏幕灭掉之后,WakeLock 还在持续,CPU 频率也降不下来。这就是典型的异常耗电场景。
14.4 Doze 模式:系统如何省电?
Android 6.0 引入了 Doze 模式。简单说,就是设备静止且屏幕关闭一段时间后,系统会进入“打盹”状态,限制网络访问和后台任务。
Doze 有几个阶段:
| 阶段 | 触发条件 | 行为 |
|---|---|---|
| Light Doze | 屏幕关闭,设备静止 | 限制网络访问,推迟 Job |
| Deep Doze | 屏幕关闭超过 30 分钟 | 完全禁止网络,禁止 WakeLock |
| Maintenance Window | 每 1-2 小时短暂退出 | 允许同步、Alarm、网络 |
你可以用 dumpsys deviceidle 查看当前 Doze 状态:
adb shell dumpsys deviceidle
mState: IDLE
mLightState: IDLE
mIdleStartTime: +1h30m20s
mLastIdleMaintenance: +1h28m15s
mState: IDLE 表示设备已经进入 Deep Doze。如果设备长时间无法进入 IDLE,说明有 App 在阻止休眠。
dumpsys power 看 WakeLock,用 dumpsys alarm 看谁在频繁设置闹钟唤醒系统。
14.5 实战:定位一个异常耗电问题
我记得有一次,用户反馈手机待机一晚掉电 30%。我拿到设备后,按以下步骤排查:
- 看电池统计:
dumpsys batterystats发现“蓝牙”耗电占比异常高。 - 看 WakeLock:
dumpsys power发现一个叫BluetoothWakeLock的锁一直没释放。 - 看 Doze 状态:
dumpsys deviceidle显示设备从未进入 IDLE。 - 抓取 bugreport:用 BatteryHistorian 分析,发现蓝牙每 10 秒唤醒一次系统。
最终定位到是蓝牙芯片的固件 bug,导致连接断开后没有释放 WakeLock。升级固件后问题解决。
dumpsys battery 显示电量正常,但手机发热严重。后来发现是某个传感器驱动在后台一直轮询,没有进入休眠。所以,不要只看电池电量,还要看 CPU 频率和传感器活动。
14.6 总结一下
电源调试,说白了就是回答三个问题:
- 谁在耗电? —— 用
dumpsys batterystats和 BatteryHistorian - 谁不让系统睡? —— 用
dumpsys power看 WakeLock - 系统睡了没有? —— 用
dumpsys deviceidle看 Doze 状态
你把这些工具用熟了,大部分功耗问题都能手到擒来。嗯,今天就聊到这里。
公众号:蓝海资料掘金营,微信 deep3321