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

就是系统调用内部API的统计结果。
基础概念
核心源码:/packages/apps/Settings/src/com/android/settings/fuelgauge/PowerUsageSummary.java
核心类:
- BatteryStatsImpl:提供App各部件运行时间。
- PowerProfile:提供部件电流数值。
问题:
- Android怎样存储与读取App耗电量信息(即:BatteryStatsImpl数据怎么来的?)
- Android怎么存储部件电流数值(即:PowerProfile数据怎么来的?)
- Android具体耗电量计算方法
(1)先看下PowerUsageSummary.java如何获取BatteryStatsImpl?



可见 BatteryStatsImpl 通过 系统服务“batteryinfo”获得。
(2)系统服务“batteryinfo”是什么玩意呢?(见:BatteryStatsService.java)

系统服务“batteryinfo”其实就是BatteryStatsService,而BatteryStatsService“唯一的”构造函数提供了一个很重要的信息:filename!
(3)BatteryStatsService在哪里创建?filename是什么?(见:ActivityManagerService.java)

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

betterystats.bin文件仅仅是一个记录不同app使用电量的一个文件。
(4)再看看 BatteryStatsImpl(String filename) 构造函数(见:BatteryStatsImpl.java)

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


至此,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

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:

字段含义见《Power Profiles for Android》。
(3)每个OEM厂商有自己独立的power_profile.xml配置
官方文档表明:OEM厂商应该有自己的power_profile.xml,因为部件(如:cpu, wifi…)耗电量应与具体硬件相关,这个只有OEM厂商清楚……

(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耗电量统计的 时间段 是?


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

可见,processAppUsage 是 上一次拔掉设备后 ~ 至今 的App耗电量统计。
【2】processAppUsage 的统计对象真的是App?

具体的 统计流程 都在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);

【4】耗电量计算公式 - 部分2:计算Uid的wake lock耗电量
这里,Android只计算了partial wake lock的耗电量。
Uid_Power2 = PartialWakeLock_Time * POWER_CPU_WAKE

【5】耗电量计算公式 - 部分3:计算Uid的数据流量(data traffic)耗电量
Uid_Power3 = ( tcpBytesReceived + tcpBytesSent ) * averageCostPerByte


【6】耗电量计算公式 - 部分4:计算Uid WIFI耗电量。
Uid_Power4 = wifiRunningTimeMs * POWER_WIFI_ON

【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
深入浅出Android App耗电量统计的更多相关文章
- [Android] 深入浅出Android App耗电量统计
reference to : http://www.cnblogs.com/hyddd/p/4402621.html 前言 在Android统计App耗电量比较麻烦,直至Android 4.4,它仍没 ...
- Android应用耗电量统计,无需USB连接
Android应用耗电量统计一直是一个很头疼的问题,手工统计耗时太长,自动化统计又不是非常精准(执行自动化代码需要通过USB连接,而USB又会充电,这就造成统计数据不准).后来从前辈那里得知可以通过a ...
- android app 流量统计
https://blog.csdn.net/yzy9508/article/details/48300265 | android 数据流量统计 - CSDN博客https://blog.csdn.ne ...
- Android性能专项测试之耗电量统计API
版权声明:本文为Doctorq原创文章,未经博主允许不得转载. https://blog.csdn.net/qhshiniba/article/details/49155979 参考文章:Androi ...
- 2.9 学习总结 之 【Android】体温统计APP
一.说在前面 昨天 学习了JQ的相关知识 今天 编写体温统计APP 我的工程源码:https://github.com/xiaotian12-call/Take-body-temperature 二. ...
- 通过 Battery Historian 工具分析 Android APP 耗电情况
电量统计模块概述 Android 从两个层面统计电量的消耗,分别为 软件排行榜 及 硬件排行榜.它们各有自己的耗电榜单,软件排行榜为机器中每个 App 的耗电榜单,硬件排行榜则为各个硬件的耗电榜单.这 ...
- [转]设计一款Android App总结
开发工具的选择 开发工具我将选用Android Studio,它是Google官方指定的Android开发工具,目前是1.2.2稳定版,1.3的预览版也已经发布了.Android Studio的优点就 ...
- 【Bugly安卓开发干货分享】Android APP 快速 Pad 化实现
项目背景 采用最新版本手机 APP(之后称为 MyApp)代码,实现其 Pad 化,为平板和大屏手机用户提供更好的体验.为实现 MyApp 的 Pad 化工作,需要我们首先来了解一下 MyApp 项目 ...
- android app自动化测试之UIAutomator
一.UIAutomator Android自动化测试工具有很多,但是要免费.易上手,本人觉得就直接使用Eclipse自带的UIAutomator就不错.测试人员无需跟开发要代码信息,只要手机上有安装之 ...
随机推荐
- PHP格式化显示文件大小函数
用filesize() 函数可以返回文件的大小,可是返回值是以字节(B)为单位的,看起来不方便.怎么让它根据文件的大小自动以KB.MB.GB为单位显示呢,用下面这个函数就可以实现了. <?php ...
- curl发送get和post请求
function getAction($url='') { // curl 请求一共分四步,初始化,设置属性,执行并获取结果,释放句柄 // 一.初始化 $curl = curl_init(); // ...
- epoll示例
书到用时方恨少,一切尽在不言中 #include <iostream> #include <sys/socket.h> #include <sys/epoll.h> ...
- Android Studio在创建/导入项目的时候,一直处于building “XXX”gradle project info的解决办法
Android Studio在新建项目或者导入项目的时候,可能会一直处于building “XXX”gradle project info的状态,而且还取消不了,无奈之下只能干掉进程... 还有一种情 ...
- spring Quartz多个定时任务的配置
Quartz多个定时任务的配置 1,配置文件与spring整合,需要在spring 的总配置中一入或者在web.xml中spring监听中加上 ztc_cp-spring-quartz.xml 注:定 ...
- javascript设计模式与开发实践
1. js面向对象6种形式(详情) <!DOCTYPE html> <html> <head lang="en"> <meta chars ...
- php多文件上传
多文件上传<input type="file" name="file[]" multiple /> <?php function reArra ...
- 【康拓展开】及其在求全排列第k个数中的应用
题目:给出n个互不相同的字符, 并给定它们的相对大小顺序,这样n个字符的所有排列也会有一个顺序. 现在任给一个排列,求出在它后面的第i个排列.这是一个典型的康拓展开应用,首先我们先阐述一下什么是康拓展 ...
- 在Salesforce中创建Approval Process
在Salesforce中可以创建Approval Process来实现审批流程的功能,实际功能与我们常说的Workflow很相似,具体的设置步骤如下所示 1):选择对应的Object去创建对应的App ...
- iOS NSOperation 封装 通知实现界面更新
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @interface MYOperation : NSOpe ...