前言

在Android统计App耗电量比较麻烦,直至Android 4.4,它仍没公开“电量统计”API或文档……额,是的,仅没有公开,并不是没有。平时在手机“设置- 电量”看到的数据

深入浅出Android App耗电量统计_第1张图片

就是系统调用内部API的统计结果。

基础概念

1. 手机由众多“部件”组成,所谓“部件”是指:CPU,WIFI,GPS....所以,AndroidApp消耗总电量为 App运行过程中,涉及各部件的消耗电量的总和。 2. 假设运行App导致CPU运行,时间:t,CPU单位时间消耗电量:w,则App的CPU耗电量为:W = w*t,而有物理公式 W = U*I*t(U:电压值,I:电流值),在手机中,一般U恒定不变,所以,可以单独通过 Q(电容量,单位: mAh)= I * t 表示电量 系统源码分析

核心源码/packages/apps/Settings/src/com/android/settings/fuelgauge/PowerUsageSummary.java

核心类

- BatteryStatsImpl:提供App各部件运行时间。

- PowerProfile:提供部件电流数值。

问题

- Android怎样存储与读取App耗电量信息(即:BatteryStatsImpl数据怎么来的?)

- Android怎么存储部件电流数值(即:PowerProfile数据怎么来的?)

- Android具体耗电量计算方法

1. Android怎样存储与读取App耗电量信息

(1)先看下PowerUsageSummary.java如何获取BatteryStatsImpl?

深入浅出Android App耗电量统计_第2张图片

深入浅出Android App耗电量统计_第3张图片

深入浅出Android App耗电量统计_第4张图片

可见 BatteryStatsImpl 通过 系统服务“batteryinfo”获得。

(2)系统服务“batteryinfo”是什么玩意呢?(见:BatteryStatsService.java

深入浅出Android App耗电量统计_第5张图片

系统服务“batteryinfo”其实就是BatteryStatsService,而BatteryStatsService“唯一的”构造函数提供了一个很重要的信息:filename!

(3)BatteryStatsService在哪里创建?filename是什么?(见:ActivityManagerService.java

深入浅出Android App耗电量统计_第6张图片

filename文件是:/data/system/batterystats.bin,关于batterystats.bin,之前民间很多文章说它用作电池校正,但Android工程师Dianne Hackborn在google+上明确:

深入浅出Android App耗电量统计_第7张图片

betterystats.bin文件仅仅是一个记录不同app使用电量的一个文件。

(4)再看看 BatteryStatsImpl(String filename) 构造函数(见:BatteryStatsImpl.java

深入浅出Android App耗电量统计_第8张图片

这里只做了些基本的初始化。真正载入betterystats.bin数据是在(ActivityManagerService.java)mBatteryStatsService.getActiveStatistics().readLocked();

深入浅出Android App耗电量统计_第9张图片

深入浅出Android App耗电量统计_第10张图片

至此,Android怎样存储与读取App耗电量信息分析结束。

总结:

(1)ActivityManagerService 创建并初始化 BatteryStatsService,并传入耗电量记录文件batterystats.bin;

(2)BatteryStatsService 在内部创建 BatteryStatsImpl 实例,并传入耗电记录文件batterystats.bin;

(3)ActivityManagerService 执行 mBatteryStatsService.getActiveStatistics().readLocked();导致 BatteryStatsService 的 BatteryStatsImpl 加载batterystats.bin数据;

(4)在PowerUsageSummary计算App耗电量时,PowerUsageSummary从BatteryStatsService 中获取BatteryStatsImpl 实例,从而获得App的相关数据。

2. Android怎么存储部件电流数值

(1)比较简单,见PowerProfile.java

深入浅出Android App耗电量统计_第11张图片

PowerProfile读取资源 com.android.internal.R.xml.power_profile,并把数据加载到sPowerMap。

(2)com.android.internal.R.xml.power_profile在哪里?

在官方文档《Power Profiles for Android》明确了power_profile.xml位置:device///frameworks/base/core/res/res/xml/power_profile.xml。

下面是一个samsung的power_profile.xml

深入浅出Android App耗电量统计_第12张图片

字段含义见《Power Profiles for Android》。

(3)每个OEM厂商有自己独立的power_profile.xml配置

官方文档表明:OEM厂商应该有自己的power_profile.xml,因为部件(如:cpu, wifi…)耗电量应与具体硬件相关,这个只有OEM厂商清楚……

深入浅出Android App耗电量统计_第13张图片

(4)PowerProfile关键API:

- public double getAveragePower(String type):返回type的电流值(mA),type表示power_profile.xml中的某关键字(如:gps.on)。

- public double getAveragePower(String type, int level) :返回type的电流值(mA),level表示xml中array的第几个value。

至此,Android怎么存储部件电流数值分析结束。

总结:

(1)Android部件电流信息存于:power_profile.xml

(2)每个OEM厂商有私有power_profile.xml

(2)PowerProfile读取power_profile.xml,并提供API访问部件电流数值。

3. Android具体耗电量计算方法

App耗电量统计:processAppUsage()

硬件耗电量统计:processMiscUsage()

processAppUsage()分析

【1】processAppUsage耗电量统计的 时间段 是?

深入浅出Android App耗电量统计_第14张图片

深入浅出Android App耗电量统计_第15张图片

关于统计的 时间段,BatteryStats有4个选项:

深入浅出Android App耗电量统计_第16张图片

可见,processAppUsage 是 上一次拔掉设备后 ~ 至今 的App耗电量统计。

【2】processAppUsage 的统计对象真的是App?

Image(16)

具体的 统计流程 都在for循环里,额……所以processAppUsage真实统计粒度是Uid。

Uid与App关系:2个App签名和sharedUserId相同,则在运行时,他们拥有相同Uid。就是说processAppUsage统计的可能是多个App的耗电量数据,对于普通App,出现这种情况的几率较少,而对于Android系统应用则较为常见。

【3】耗电量计算公式 - 部分1:计算Uid属下每个Process的耗电量数据,并求和。

Uid_Power1 = (Process1_Power + … + ProcessN_Power);

Process_Power = (CPUSpeed_Time * POWER_CPU_ACTIVE);

深入浅出Android App耗电量统计_第17张图片

【4】耗电量计算公式 - 部分2:计算Uid的wake lock耗电量

这里,Android只计算了partial wake lock的耗电量。

Uid_Power2 = PartialWakeLock_Time * POWER_CPU_WAKE

深入浅出Android App耗电量统计_第18张图片

【5】耗电量计算公式 - 部分3:计算Uid的数据流量(data traffic)耗电量

Uid_Power3 = ( tcpBytesReceived + tcpBytesSent ) * averageCostPerByte

Image(19)

深入浅出Android App耗电量统计_第19张图片

【6】耗电量计算公式 - 部分4:计算Uid WIFI耗电量。

Uid_Power4 = wifiRunningTimeMs * POWER_WIFI_ON

Image(21)

【7】耗电量计算公式 - 部分5:计算Uid其他传感器耗电量。

Uid_Power5 = (Sensor1_Power + … + SensorN_Power)

Sensor_Power = Sensor_Time * Power_Sensor

至此,App耗电量计算方法分析结束。硬件耗电量统计(processMiscUsage())亦类似。

总结App耗电量计算公式:

Uid_Power(App耗电量,单位:mAh) = Uid_Power1 + Uid_Power2 + Uid_Power3 + Uid_Power4 + Uid_Power5

Uid_Power1 = (Process1_Power + … + ProcessN_Power);

- Process_Power = (CPUSpeed_Time * POWER_CPU_ACTIVE);

Uid_Power2 = PartialWakeLock_Time * POWER_CPU_WAKE

Uid_Power3 = ( tcpBytesReceived + tcpBytesSent ) * averageCostPerByte

Uid_Power4 = wifiRunningTimeMs * POWER_WIFI_ON

Uid_Power5 = (Sensor1_Power + … + SensorN_Power)

- Sensor_Power = Sensor_Time * Power_Sensor

说这么多,来一发……不,来一个统计耗电量的App吧,其实,之前已有人把这段Android系统代码抠出来,做了一个App,可以到这里下载。 --------------我是一个分割线--------------

有一个好消息是:android5.0后,获取电量数据不用这么痛苦了,dumpsysbatterystats数据中。包含:Estimated power use (mAh):,下面就是每个uid的耗电量,只要把app下所有uid耗电量加起来即可!


更多相关文章

  1. Android中应用程序drawable图片资源占用内存的统计
  2. WebView加载图片闪与Android的硬件加速
  3. 【Android开发 .9图的使用】Android Studio中关于.9.png图片的使
  4. 说说在 Android 中如何压缩图片
  5. android 图片占用进程的内存算法
  6. Android Fresco图片加载库基础使用详解
  7. Android React Native加载图片资源的正确姿势
  8. 【移动开发】Android中图片过大造成内存溢出,OOM(OutOfMemory)异常
  9. Android仿淘宝首页UI(附代源代码及示例图片)

随机推荐

  1. Android移动应用基础学习——第一章基础
  2. Android2.3 中如何使用GPU硬件加速
  3. Android中实现网络图片的获取
  4. Android面试题精选
  5. Android学习之ION memory manager
  6. Android应用开发学习之相对布局
  7. 简单的Android对文件进行读写操作
  8. Android内存之VSS/RSS/PSS/USS
  9. 2011.10.09——— android ImageView放大
  10. Mono for Android 篇一 环境的搭建