
7.1 什么是 Power Profile简单来说power_profile.xml就是 Android 系统用来描述硬件功耗的“说明书”。它告诉系统CPU 在不同频率下消耗多少电流屏幕在不同亮度下消耗多少电流Wi-Fi、蓝牙、GPS 等模块工作时消耗多少电流……等等系统拿到这些数据后才能估算出每个 App、每个进程到底用了多少电。你想想看如果这个说明书是错的那后面所有的功耗分析结果都是扯淡。核心观点Power Profile 是功耗计算的“基准”。基准不准一切白搭。7.2 文件结构长什么样这个文件通常放在/vendor/etc/power_profile.xml或/system/etc/power_profile.xml下。我们来看看它的骨架?xml version1.0 encodingutf-8? device nameAndroid item namescreen.on200/item item namescreen.full300/item item namewifi.on50/item item namewifi.active150/item item namebluetooth.on10/item item namebluetooth.active80/item item namegps.on100/item item nameradio.active200/item item nameradio.scanning100/item array namecpu.clusters.cores value4/value value4/value /array array namecpu.core_speeds.cluster0 value300000/value value600000/value value1200000/value value1800000/value /array array namecpu.core_power.cluster0 value50/value value100/value value200/value value400/value /array /device看到没结构其实很简单。根节点是device里面一堆item和array。每个item描述一个独立模块的功耗每个array描述一组关联数据比如 CPU 不同频率下的功耗。7.3 关键参数详解我个人习惯把参数分成三类这样好记类别参数名含义单位屏幕screen.on屏幕点亮时的基础功耗mAscreen.full屏幕最高亮度时的额外功耗mAWi-Fiwifi.onWi-Fi 开启但未传输数据mAwifi.activeWi-Fi 正在传输数据mACPUcpu.core_speeds.cluster0CPU 簇0支持的频率列表kHzcpu.core_power.cluster0对应频率下的功耗mA射频radio.active蜂窝数据活跃时功耗mA这里要注意一个细节单位都是毫安mA不是毫瓦mW。为什么用电流而不是功率因为 Android 的电池电压是固定的通常 3.7V 或 4.2V用电流更方便计算。系统内部会再根据电压换算成功率。小技巧如果你拿到一台新设备想快速验证 power_profile 是否准确可以这样做充满电记录电量百分比然后播放 1 小时 1080p 视频再记录电量。用 BatteryStats 导出的数据反推功耗和 power_profile 里的值对比。偏差超过 20% 的话建议找厂商要真实数据。7.4 如何配置设备功耗参数配置 power_profile 说白了就是“填数字”。但数字从哪来我分享三种方法查芯片手册高通、MTK 的芯片文档里通常会给出典型功耗值。这是最权威的来源。实测用精密电源如 Agilent N6705B给设备供电运行特定场景直接读电流。这是最准确的方法。估算如果前两种都做不到可以参考同平台设备的数值再根据电池容量和续航时间反推。这是最不推荐的方法但应急时可以用。我曾经在一个项目里厂商给的 power_profile 里 CPU 功耗值偏低了 30%。结果系统算出来的功耗比实际少了将近一半导致所有功耗优化措施都像是在“盲人摸象”。后来我们借了台精密电源花了两天时间把所有模块的电流重新测了一遍才把问题解决。避坑指南千万不要直接复制其他机型的 power_profile不同芯片、不同屏幕、不同射频模块的功耗差异巨大。我曾经见过有人把骁龙 865 的配置直接套在骁龙 8 Gen 1 上结果功耗估算完全乱套。7.5 自定义功耗模型有时候标准的 power_profile 满足不了我们的需求。比如你的设备有特殊的传感器如红外测温模块你想为某个特定场景如游戏模式建立更精细的功耗模型系统默认的功耗估算算法不够准确你想自己算这时候就需要自定义功耗模型了。怎么做我一般走这几步第一步扩展 power_profile在device节点下添加自定义的item或array。比如item namecustom.sensor.ir15/item array namecustom.gpu.freqs value200000/value value400000/value value600000/value /array array namecustom.gpu.power value80/value value150/value value250/value /array第二步修改功耗计算逻辑在frameworks/base/services/core/java/com/android/server/power/PowerProfile.java中添加读取自定义参数的方法。比如public long getCustomPower(String name) { return getItem(name); } public long[] getCustomArrayPower(String name) { return getArray(name); }第三步在 BatteryStats 中调用在BatteryStatsImpl.java中根据你的自定义参数计算功耗。这部分代码比较深我建议你先理解系统默认的计算流程再动手改。说实话自定义功耗模型是个“大工程”。我一般只在以下情况才会做项目有特殊硬件系统不支持功耗估算偏差超过 30%且无法通过调整 power_profile 解决客户明确要求自定义功耗统计7.6 知识体系总览为了帮你理清思路我画了张图这张图展示了 power_profile 从数据来源到最终输出的完整链路。你可以看到它处于整个功耗分析流程的“上游”直接影响下游所有计算结果的准确性。7.7 写在最后Power Profile 这个东西说简单也简单就是个 XML 文件。但说复杂也复杂因为里面的每一个数字都决定了你的功耗分析准不准。我个人建议拿到一台新设备后第一件事就是去检查 power_profile。打开文件看看数值是否合理和芯片手册对一对。如果发现明显异常赶紧找厂商确认。别等到分析到一半才发现问题那时候就晚了。