最轻量可控的自动化方案是用 adb shell dumpsys batterystats 抓取原始数据并用 python 解析,需先重置统计、指定包名采集、提取 estimated power use、uid 耗电和 wake lock 时间三个关键字段,禁用 psutil.sensors_battery() 等无效方法。

直接用 adb shell dumpsys batterystats 抓取原始数据,再用 Python 解析关键字段,是目前最轻量、最可控的自动化方案。Battery Historian 适合深度归因分析,但不适合嵌入 CI 或批量回归——它依赖本地服务、编译复杂、不支持 headless 批量上传。
如何用 Python 调用 adb 获取实时耗电快照
Android 系统每秒都会更新电池统计缓存,dumpsys batterystats 输出的是自上次重置以来的累积值,不是实时功耗。所以必须先重置、再操作、最后采集,否则数据混杂不可比。
- 重置命令必须成对执行:
adb shell dumpsys batterystats --reset+adb shell dumpsys batterystats --enable full-wake-history(后者确保唤醒锁被记录) - 采集时建议指定包名,避免全系统噪声干扰:
adb shell dumpsys batterystats com.example.app | grep -A 20 "Estimated power use" - Windows 用户注意:
grep要换成findstr,且正则能力弱,推荐用 Python 的re.search(r'Estimated.*?(\d+\.?\d+) mAh', output)提取数值 - 不要依赖
adb bugreport生成 zip —— 它体积大、解析慢、格式不固定,仅适合人工上传 Battery Historian
解析 batterystats 输出时最容易漏掉的三个字段
dumpsys batterystats 的文本结构松散,同一行可能含多个指标,靠行号或关键词定位极易错位。真正稳定的提取目标是以下三个带单位的数值字段:
-
Estimated power use:整机估算耗电量(单位 mAh),位于输出头部,是宏观参考值 -
Power use for UID:对应 App 的 UID 耗电(单位 mAh),需先用adb shell dumpsys package com.example.app | grep userId=拿到 UID,再匹配Power use for UID 10123后的数值 -
Wake lock行中的time:后数值(单位 ms):反映后台唤醒时长,高值往往对应异常耗电,比单纯看 mAh 更早暴露问题
为什么不能只用 psutil.sensors_battery() 测移动设备
psutil.sensors_battery() 只适用于桌面系统(Windows/macOS/Linux),在 Android 上完全不可用——Python 进程运行在 PC 端,无法直接读取手机电池芯片寄存器。所有“手机电量监控”类文章若直接调用该函数,本质是测你电脑的电量,和被测 App 零关系。
- 真机耗电必须走 ADB 桥接,这是唯一受 Android 系统信任的数据通路
- 部分文章用
adb shell dumpsys battery,它只返回当前电量百分比和状态(如level: 85),没有历史累计值,无法用于对比测试 - 若需温度数据,要用
adb shell dumpsys battery | grep temperature,单位是 0.1℃(如temperature: 324= 32.4℃),注意别直接当摄氏度用
自动化脚本中必须加的防错逻辑
真实测试环境里,ADB 断连、手机休眠、权限拒绝、包名拼错这四类错误占全部失败的 80% 以上。Python 脚本里不显式处理,日志里只会看到空字符串或 IndexError,根本看不出哪步挂了。
- 每次
os.popen()或subprocess.run()后,检查returncode != 0和输出是否为空;例如:if not output.strip(): raise RuntimeError("adb command returned empty") - 获取 UID 前,先用
adb shell pm list packages | grep com.example.app确认包名存在 - 设置超时:用
subprocess.run(..., timeout=10),避免 adb 卡死阻塞整个流水线 - 别把“电量下降值”当绝对耗电量——不同手机电池容量差异极大(4000mAh vs 6000mAh),应统一换算成
mWh或使用相对变化率(如“测试期间下降 12%”)
真正难的不是取数,而是让每次采集的上下文一致:屏幕亮度、网络类型、后台进程、电池初始温度,这些变量不锁死,跑十次结果能差 3 倍。自动化脚本能跑通只是第一步,稳态控制才是耗电测试的分水岭。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











