Android性能测试之耗电量测试

来源:互联网 发布:javascript 书 知乎 编辑:程序博客网 时间:2024/05/11 23:24

参考文章:

1,http://bbs.mumayi.com/thread-3891680-1-1.html:

2,http://www.bubuko.com/infodetail-1151349.html:对最新的android6 耗电量获取方法做了说明;

3,http://www.cnblogs.com/hyddd/p/4402621.html :深入浅出Android App耗电量统计

4,http://blog.sina.com.cn/s/blog_a6559d920101k0av.html:android底层电量分析;

5,http://blog.csdn.net/jiangwei0910410003/article/details/25994337:Android中的隐藏API和Internal包的使用之获取应用电量排行


5.http://blog.csdn.net/tangdl86/article/details/46958175 :分析了android4.0以上版本耗电量获取的方法,能够准确获取耗电量各个纬度的信息,但是由于android系统的碎片化,先不能支持android4.4以及部分其他设备;


6. http://blog.csdn.net/w263044840/article/details/45338645 : android常见耗电量监控工具做测试时的优缺点



android APP耗电量基本概念:

基础概念

    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 表示电量

扒开源代码瞧了一下,发现这里别有洞天!Android其实很早就开始做耗电量的统计,已经取得了长足的进步,比linux的耗电量统计强了不止一个等级。google一直不开放相关的API, 可能是因为这个功能还不成熟吧。对比了一下Android4.1, android4.4, android5.1的源代码, 发现思路是一致的, 但后面的版本比前面的版本更加细致, 且使用的类也有所变化。 为简单起见,这里以androd5.1版本为例进行讲解。相关的源码我会和本文一起打包, 有兴趣的同学可以看一下。

代码的入口,当然是“设置”中的“电池”界面啦。为了省事,大家直接看这个包“com.android.settings.fuelgauge”, 优先看里面的PowerUsageSummary类。它的注释这样写到:“Displaysa list of apps and subsystems that consume power, ordered by how much power wasconsumed since the last time it was unplugged.” 大意是说, 将应用自从上次拔下USB线后的耗电量排成列表。 我们就从这里一步步深入代码。

这段注释有问题,android4.4以前的系统默认以上次拔下USB线为起点计算耗电量,android4.4-5.1是以上次充满电为起点)

PowerUsageSummary类的作用,是筛选耗电量最多的前10个应用,并且展示。真正计算耗电量数据的,是com.android.internal.os.BatteryStatsHelper, 它计算所有应用的耗电。这个计算方法很有趣, 有点象在超市购物: 有一张“价格表”,记录每种硬件1秒钟耗多少电。有一张“购物清单”,记录apk使用了哪几种硬件,每种硬件用了多长时间。假设iTest这款apk累计使用了60秒的cpu,cpu1秒钟耗1mAh。那iTest本次就占用了60mAh的电。实际的算法比这个例子复杂很多。有兴趣的同学可以查看BatteryStatsHelper类的processAppUsage方法。

从这里可以看出,android自带的耗电量统计的准确性,受两个大方面的因素影响:


一是那张“价格表”,由PowerProfile类提供。手机的硬件是各不相同的,所以每一款手机都会有一张自己的“价格表”。这张表的准确性由手机厂商负责,所以,尽量用大厂的机子,并且只使用该厂商提供的Android系统。 

 

二是那张“购物清单”,这是Android的BatteryStatsService类提供的。上文说到的BatteryStatsHelper类使用AIDL调用BatteryStatsService类的getStatisticsStream方法获取相关数据。


今天老大安排一个任务叫我获取手机中应用耗电排行(时间是前天晚上7点到第二天早上10点),所以在网上各种搜索,没想到这种资料还是很多的,发现了一个主要的类:PowerProfile,但是可以的是,这个类没有曝光给我们开发者,所以我们不能调用它

那怎么办呀?,还是有办法的,这个类是藏在:com.android.internal.os.PowerProfile

com.android.internal.os.PowerProfile.PowerProfile这个类就是负责解析记录文件,我们可以创建一个它的对象,通过该对象来获取具体信息。具体耗电计算比较复杂

下面来看一下案例:Demo是对2.3.3的settings源码修改的

(Demo下载地址:http://download.csdn.net/detail/jiangwei0910410003/7357717)

主要是给那些没有研究过这部分源码的同学。
settings中获取手机电量排行的原理主要是通过读取电池记录文件来实现的。主要用到了android.os.BatteryStats这个隐藏类和com.android.internal这特殊的个包。
隐藏类都好解决,主要是internal包,该包不但android.jar中没有,及时你找到该包,把它放到android.jar中,你会发现也是用不了的。原因是ADT对这个包加了限制。不让使用。


一种解决办法是修改ADT,将该限制去掉。(这种方式是很难实现的)
另外一种就是不把internal放到android.jar中,把他单独作为一个包导入到工程中,这样就不会被限制了


我们采用第二种方案去解决,这种方法也是最简单的

就是将这个包直接导入我们的工程,在工程中就可以使用隐藏API和Internal包了。
我们可以使用该包单独做一个平台,这在后面再讲。

注意:该包不能直接放在libs目录里面,请放到其他地方。因为ADT屏蔽了Internal包,直接放在libs下ADT会检测到。且放在外面的文件是不会打包到我们的apk文件中的,所以还可以减小了apk文件的体积。同理得出非系统包就一定要放在libs下,否则程序运行的时候就会报找不到包的错误。


下面就来看看到底如何制作这个jar包:

首先我们要明白为什么隐藏API(有@hide标记)和Internal包不能使用。

当我们使用android的SDK进行开发的时候都会用到一个非常重要的jar文件--android.jar(Android SDK目录/platforms/platform-X/android.jar,X是API等级)。这个包中移除了所有被标记的尾@hide的类、方法、枚举、字段和Internal包。当我们的程序在设备上运行的时候会加载设备上的一个framework.jar的文件,它包含了移除的部分。


所以我们的思路是想办法得到framework.jar将那些缺少的API拿出来放到android.jar中。当然这些都可以通过编译源码来解决,但那样太过麻烦。下面我介绍一种简单的方法来获取这些内容。


 

 






0 0