深入浅出Android App耗电量统计

前言

在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,可以到 这里下载

作者:hyddd
出处:http://www.cnblogs.com/hyddd/
本文版权归作者所有,欢迎转载,演绎或用于商业目的,但是必须说明本文出处(包含链接)。

时间: 2024-10-27 09:45:07

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

[Android] 深入浅出Android App耗电量统计

reference to : http://www.cnblogs.com/hyddd/p/4402621.html 前言 在Android统计App耗电量比较麻烦,直至Android 4.4,它仍没公开“电量统计”API或文档……额,是的,仅没有公开,并不是没有.平时在手机“设置- 电量”看到的数据 就是系统调用内部API的统计结果. 基础概念 1. 手机由众多“部件”组成,所谓“部件”是指:CPU,WIFI,GPS....所以,Android App消耗总电量为 App运行过程中,涉及各部件

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

Android应用耗电量统计一直是一个很头疼的问题,手工统计耗时太长,自动化统计又不是非常精准(执行自动化代码需要通过USB连接,而USB又会充电,这就造成统计数据不准).后来从前辈那里得知可以通过adb connect来实现无线连接,下面就来说说方法. 1.首先找到一台已经root的手机 2.使手机与PC处于同一个网段 3.下载安装Wireless ADB 4.打开Wireless ADB,勾选Wireless ADB,设置端口(默认5555,被占用时设置) 5.打开pc的CMD窗口,输入ad

android app 流量统计

https://blog.csdn.net/yzy9508/article/details/48300265 | android 数据流量统计 - CSDN博客https://blog.csdn.net/forlong401/article/details/8440160 | android如何开发流量监控软件 - CSDN博客https://stackoverflow.com/questions/12613402/android-statistic-3g-traffic-for-each-ap

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

参考文章:Android应用的耗电量统计 深入浅出Android App耗电量统计 Battery stats - CPU total vs CPU foreground 深入浅出 Android App 耗电量统计 浅析Wakelock机制与Android电源管理 耗电量API Android系统中很早就有耗电量的API,只不过一直都是隐藏的,Android系统的设置-电池功能就是调用的这个API,该API的核心部分是调用了com.android.internal.os.BatteryStat

android产品研发(八)-->App数据统计

转载请标明出处:一片枫叶的专栏 上一篇文章中我们介绍了android社区中比较火的热修复功能,并介绍了目前的几个比较流行的热修复框架,以及各自的优缺点,同时也介绍了一下自身项目中对热修复功能的实践.目前主流的热修复原理上其实分为两种,一种是通过利用dex的加载顺序实现热修复功能,一种是通过native层实现指针替换实现热修复功能,两种各有利弊可以根据自身产品的需要选择不同的方案. 而文本将要介绍一下android产品中另一项基础功能-数据统计.App数据统计的意义在于通过统计用户的行为方式有针对

【转】Android APP性能测试

性能测试是通过自动化的测试工具模拟多种正常.峰值以及异常负载条件来对系统的各项性能指标进行测试.而app的性能也越来越被关注,下面我们就介绍一下app的性能测试方法.但是性能测试是参考值,不管什么测试方法都不可能精确地测试出被测试对象的真实性能指标,这一点要事先明确.一.内存泄露Android内存抓取步骤准备:电脑需安装android adb 并将adb的目录加入到系统环境变量中,通过电脑命令窗口来查看内存变化状况,并记录内存数值步骤:a.adb devices -l 查看手机设备是否连接上,如

Android应用流量统计——NetworkStatsManager使用

在没有Root的情况下,Android应用流量统计在6.0之前一直没有太好的办法,官方虽然提供了TrafficStats,但其主要功能是设备启动以来流量的统计信息,和时间信息无法很好的配合.最近再看TrafficStats类时,发现说明中提到,为获取更具鲁棒性的网络历史数据,建议使用NetworkStatsManager. 本文首先简单对比下TrafficStats和NetworkStatsManager各自的限制和优缺点,然后详细说明NetworkStatsManager的用法,并给出主要代码

Android App组件之ListFragment -- 说明和示例(转载)

转自:http://www.cnblogs.com/skywang12345/p/3160260.html 1 ListFragement介绍 ListFragment继承于Fragment.因此它具有Fragment的特性,能够作为activity中的一部分,目的也是为了使页面设计更加灵活. 相比Fragment,ListFragment的内容是以列表(list)的形式显示的. 1.1 ListFragment布局 ListFragment的布局默认包含一个list view.因此,在List

android app自动化测试之UIAutomator

一.UIAutomator Android自动化测试工具有很多,但是要免费.易上手,本人觉得就直接使用Eclipse自带的UIAutomator就不错.测试人员无需跟开发要代码信息,只要手机上有安装之后的APP自己就能做出自动测试用例,况且一通百通,就算是不满足于UI测试的,找个简单易上手的先明白原理,再深入了解其它复杂工具也会轻松很多.何乐而不为呢? UIAutomator是Eclipse自带的用于UI自动化测试工具,可仿真APP上的单击.滑动.输入文本等操作. 在使用之前,需要安装好java