reference to : http://www.cnblogs.com/hyddd/p/4402621.html

前言

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

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

基础概念

    1. 手机由众多“部件”组成,所谓“部件”是指:CPU,WIFI,GPS....所以,Android App消耗总电量为 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?

可见 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

 
            说这么多,来一发……不,来一个统计耗电量的App吧,其实,之前已有人把这段Android系统代码抠出来,做了一个App,可以到 这里下载
 
--------------我是一个分割线--------------
 
            有一个好消息是:android5.0后,获取电量数据不用这么痛苦了,dumpsys batterystats数据中。包含:Estimated power use (mAh):,下面就是每个uid的耗电量,只要把app下所有uid耗电量加起来即可!

[Android] 深入浅出Android App耗电量统计的更多相关文章

  1. 深入浅出Android App耗电量统计

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

  2. Android性能专项测试之耗电量统计API

    版权声明:本文为Doctorq原创文章,未经博主允许不得转载. https://blog.csdn.net/qhshiniba/article/details/49155979 参考文章:Androi ...

  3. Android 深入浅出 - Android系统启动过程

    Activity的类继承关系及跟踪Activity的启动 Android系统启动过程 https://study.163.com/course/courseLearn.htm?courseId=213 ...

  4. android app 流量统计

    https://blog.csdn.net/yzy9508/article/details/48300265 | android 数据流量统计 - CSDN博客https://blog.csdn.ne ...

  5. Android应用耗电量统计,无需USB连接

    Android应用耗电量统计一直是一个很头疼的问题,手工统计耗时太长,自动化统计又不是非常精准(执行自动化代码需要通过USB连接,而USB又会充电,这就造成统计数据不准).后来从前辈那里得知可以通过a ...

  6. 深入浅出 - Android系统移植与平台开发(六)- 为Android启动加速

    作者:唐老师,华清远见嵌入式学院讲师. Android的启动速度一直以来是他的诟病,虽然现在Android设备的硬件速度越来越快,但是随着新 版本的出现,其启动速度一直都比较慢,当然,作为程序员,我们 ...

  7. 深入浅出 - Android系统移植与平台开发(五)- 编译Android源码(转)

    2.3编译Android源码 Android源码体积非常庞大,由Dalvik虚拟机.Linux内核.编译系统.框架代码.Android定制C库.测试套件.系统应用程序等部分组成,在编译Android源 ...

  8. 转: Android 后台任务型App多进程架构演化

    评注:android 后台分进程保活方式的实践 Android 后台任务型App多进程架构演化 字数1621 阅读2790 评论8 喜欢35 什么是后台任务型app 类似音乐.录音机,需要用户长时间在 ...

  9. Android应用发布后的统计——百度移动统计的应用

    一个App发布到各个渠道之后,我们需要采集不同渠道的一些信息,比如app在运行过程中产生的一些异常信息,app在各个android版本的分布,以及各个app版本的分布,各渠道的用户数,用户忠诚度等等信 ...

随机推荐

  1. UI第三节—— UITextField详解

    戏言:UITextField对于需要登陆注册的界面的作用还是相当明显,但是对于键盘过的遮挡问题,可是重点哦!这里就涉及到通知(NSNotificationCenter)的内容. //注册事件 [[NS ...

  2. Hadoop 之MongoDB

    NoSql 简介: COUCH DB REDIS MONGODB NEO4J HBASE BIGTABLE 存储非结构化数据 索引多:单键,多键,数组,全文,2D. MonggoDB数据类型: nul ...

  3. Android 实现简单音乐播放器(二)

    在Android 实现简单音乐播放器(一)中,我介绍了MusicPlayer的页面设计. 现在,我简单总结一些功能实现过程中的要点和有趣的细节,结合MainActivity.java代码进行说明(写出 ...

  4. mac 下 xampp 多域名 多站点 多虚拟主机 配置

    前言:最近用mac工作了,需要搭建个调试前段程序的站点,选了xampp,需求是能同时运行多个站点,多个域名,目录自定义,网上找了好多资料,都感觉有些不符合心意,且复制文确实很多,甚至有些没实践过的在乱 ...

  5. JAVA操作ORACLE数据库的存储过程

    一.任务提出 JAVA操作oracle11g存储过程实验需要完成以下几个实例: 1.调用没有返回参数的过程(插入记录.更新记录) 2.有返回参数的过程 3.返回列表的过程 4.返回带分页的列表的过程. ...

  6. 外国类似stackoverflow这样的网站访问慢怎么解决-遁地龙卷风

    第二版 百度搜索蓝灯 下载桌面版 双击运行 如果打开的浏览器不是你想要的 拷贝地址栏地址给你想要的浏览器 一切就ok了!!!!! 建议不访问国外网站时,便将蓝灯关掉,否则在访问一些不开蓝灯能够正常访问 ...

  7. Android 网络请求框架android-async-http问题

    今天通过接口请求服务器的一些app数据,发现一个很奇怪的问题,请求一个链接的时候,通常在第一次请求发起的时候没有什么问题,能很快的拿到数据,但是 往后再去请求的时候就会等待很久,而且最后会请求失败,一 ...

  8. 【转】将datatable数据转化成list

    #region 将datatable数据转化成list   public static List<T> ToList<T>(this DataTable dt) where T ...

  9. hibernate 的三种状态 如何转化的。

    1. 临时状态  由 new命令开辟内存空间的java对象,例如: User user=new User(); 临 时对象在内存孤立存在,它是携带信息的载体,不和数据库的数据有任何关联关系.   2. ...

  10. JS对于数据常见操作

    var _mozi=['墨家','墨子','墨翟','兼爱非攻','尚同尚贤']; $.each(_mozi,function(key,val){//先key 后值 循环 console.log(ke ...