24、功耗问题定位:常见功耗问题(待机异常、亮屏耗电、游戏发热)、分析思路
功耗问题,说白了就是手机「跑得快」和「吃得少」之间的平衡。我做了这么多年系统优化,最怕半夜收到测试同学的消息:「机器待机一晚上掉了20%电」。嗯,这种问题往往不是单一原因造成的,得一步步拆。
今天咱们就聊聊最常见的三类功耗问题:待机异常、亮屏耗电、游戏发热。我会结合自己的实战经验,把分析思路掰开揉碎讲清楚。
一、待机异常:手机睡着了还在偷偷耗电
待机异常是我个人排查最多的功耗问题。你想想看,手机屏幕都黑了,按理说应该进入「深睡」状态,结果一觉醒来电量掉了8%甚至更多。这背后通常有几个「元凶」。
1.1 唤醒源(Wakeup Source)排查
我最常用的命令是 adb shell dumpsys power,直接看 Wake Locks 列表。如果发现某个 App 长时间持有 PARTIAL_WAKE_LOCK,那基本就是它了。
核心思路:谁在阻止系统进入 Suspend?
具体操作步骤:
- 执行
adb shell dumpsys power | grep "Wake Locks" -A 20 - 看 ACQUIRED 状态的锁,重点关注时长超过 1 分钟的
- 用
adb shell cat /sys/kernel/debug/wakeup_sources看内核级唤醒源
我曾经遇到一个案例:某视频 App 在后台播放「静音广告」,持有一个 Audio 相关的 Wake Lock 不放。用户以为退出了,实际上系统根本没法睡。嗯,这种问题用上面的命令一抓一个准。
1.2 AlarmManager 对齐问题
Android 的 AlarmManager 允许 App 设置定时唤醒。如果每个 App 都设一个独立的时间点,系统就得频繁醒来。我建议用 adb shell dumpsys alarm 查看所有闹钟的触发时间。
我的习惯:把触发时间相近的闹钟「对齐」到同一个窗口。比如 10:00:01 和 10:00:05 的闹钟,统一在 10:00:05 触发。这样系统只需要醒来一次。
1.3 Modem 驻网状态
信号差的地方,手机为了保持连接会加大发射功率。这个功耗甚至比亮屏还高。你可以用 adb shell dumpsys telephony.registry 查看信号强度。
| 信号等级 | 典型功耗影响 | 建议 |
|---|---|---|
| 良好(-85 dBm 以上) | 正常 | 无需处理 |
| 一般(-95 ~ -85 dBm) | 增加 10%~20% | 检查天线匹配 |
| 差(-95 dBm 以下) | 增加 50% 以上 | 建议用户切换飞行模式 |
二、亮屏耗电:屏幕一亮,电量哗哗流
亮屏耗电是用户感知最强的。你想想看,刷个抖音半小时掉电 15%,用户肯定骂娘。这里我重点讲三个方向。
2.1 屏幕亮度与刷新率
屏幕是耗电大户,尤其是 OLED 屏。亮度从 50% 调到 100%,功耗可能翻倍。我个人习惯用 adb shell dumpsys display 查看当前亮度值和背光曲线。
另外,高刷新率(90Hz/120Hz)在滑动场景下确实爽,但静态页面如果也跑 120Hz 就是浪费。我建议检查 LFR(Low Frame Rate) 策略是否生效。
注意:有些 App 会强制请求高刷新率,比如地图类 App 的滚动列表。这时候需要跟 App 团队沟通,让他们在非交互场景下调回 60Hz。
2.2 GPU 渲染负载
用 adb shell dumpsys gfxinfo 可以看每一帧的渲染时间。如果 Draw 或 Process 阶段超过 16ms,说明 GPU 压力大。
我记得有一次,某个电商 App 的首页背景用了实时模糊效果,GPU 负载直接拉满。去掉模糊后,功耗降了 30%。说白了,视觉特效是要用电来换的。
2.3 后台网络请求
亮屏时如果 App 频繁发起网络请求,Modem 会一直处于活跃状态。用 adb shell netstat 或者 adb shell dumpsys netstats 可以看连接数。
我建议重点关注:
- 是否有 App 每 5 秒发一次心跳包?
- 图片是否做了预加载?一次加载 50 张图,Wi-Fi 模块得忙活半天。
- 是否使用了 GCM/FCM 推送?不要自己维护长连接。
三、游戏发热:性能与功耗的终极博弈
游戏发热是用户投诉的重灾区。你想想看,手机烫得拿不住,谁还愿意玩?这里我主要讲 CPU/GPU 的调频策略。
3.1 CPU 频率与温控
用 adb shell cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq 可以看实时频率。如果发现 CPU 长时间跑在最高频,那发热是必然的。
我建议检查 Governor 策略。比如 schedutil 比 performance 更省电,但响应会慢一点。游戏场景下,可以适当放宽温控阈值,但别太激进。
核心思路:找到「性能不掉帧」和「温度不烫手」的平衡点。这个点通常需要反复调参。
3.2 GPU 降频策略
游戏对 GPU 的要求很高。用 adb shell cat /sys/class/kgsl/kgsl-3d0/gpuclk 可以看 GPU 频率。如果发现 GPU 频繁降频,说明散热压不住了。
我曾经在某个项目上,把 GPU 的 thermal throttle 温度从 65°C 调到 70°C,游戏帧率稳定了,但外壳温度高了 2°C。嗯,这就是取舍。
3.3 热管理策略
Android 的热管理框架(Thermal HAL)会监控多个温度传感器:CPU、GPU、电池、充电 IC。当温度超过阈值时,系统会主动限频。
用 adb shell dumpsys thermalservice 可以看当前的温控状态。如果看到 CPU throttling 或 GPU throttling 的日志,说明已经触发降频了。
我的建议:在游戏测试时,同时抓取 systrace 和 thermal 日志。这样能清楚看到「温度上升 → 触发限频 → 帧率下降」的完整链路。
四、分析思路总结
说了这么多,其实分析功耗问题的思路就三步:
- 抓数据:用 BatteryStats、Kernel Trace、PerfDog 等工具采集原始数据。
- 找异常:对比基线数据,看哪个模块的功耗异常高。
- 定方案:是 App 的问题就找 App 团队,是驱动的问题就调参数,是硬件的问题就改设计。
我个人习惯在项目初期就建立功耗基线。比如待机电流 < 5mA,亮屏刷微博 < 400mA,游戏 < 800mA。一旦偏离基线,马上定位。别等到用户反馈了才去查,那时候就晚了。
好了,这一章的内容就到这里。记住,功耗问题没有银弹,只有耐心和细致的排查。
公众号:蓝海资料掘金营,微信deep3321