TA的每日心情 | 慵懒 2017-7-9 10:38 |
---|
签到天数: 13 天 连续签到: 1 天 [LV.3]测试连长
|
针对Android的电量优化,应该是很多开发者最关心的几大问题之一。
最近我正在看相关的资料,希望跟大家一起探讨学习。
关于电量,我们最需要处理的问题就是两个方向:
(1)第三方APP和系统本身是如何获取电量值并展示的?我们能否针对他们的算法做适度优化?或者规避部分统计?
(2)其他代码级别优化。从业务逻辑出手,架构上适度调整的手段有哪些?
就上面2个问题,我们开始展开讨论:
(1)APP获取电量算法。
经过查看源码,以及各种资料。最后我们看到app计算电量的算法如下:
在主Activity里面 info.getBatteryStats() 就搞定了。 首先 load(),如果load失败,走CPU时间计算,通过getAppListCpuTime这样函数。 1
CPU的时间计算,有3个核心步骤:
1 ActivityManager遍历runningApp进程,获取对应pid
2 getAppProcessTime(pid)通过读取/proc/pid/stat文件,拿取APP在CPU的运行时间。
3 重新为BatterySipper附值:+time;
2
获取APP消耗 processAppUsage();也分三步走:
1 通过PowerProfile 获取cpu的速度层次(speedsteps),方便后面使用
2 根据不同CPU的速度等级,计算cpu在某个速度下的电量,mA毫安
3
mPowerProfile.getAveragePower(PowerProfile.POWERCPUACTIVE,p)
很多地方都用刀这个API获取power。
那它究竟做了些什么呢?
查看系统源码可以知道:
实际上这句话是获取1个叫PowerMap的数据结果,获得电量。而PoweMap的赋值,是来源于com.android.internal.R.xml.powerprofile 的文件。
关于该文件的获取 android-版本号/core/res/res/xml/powerprofile.xml
计算各种耗电量的详细算法是:
(1)计算CPU
BatteryStateImpl.getUidStats()获取数据源
遍历数据源,得到ProcessState
通过ProcessState拿到以下几个指标
userTime
systemTime
foregroundTime
CpuFgTime(cpuFgTime+= foregroundTime10;)
cpuTime (cpuTime+=tmpCpuTime)
tmpCpuTime=(userTime + systemTime)10
power +=processPower
4
(2)计算wake lock
wakelock,只关心partial的类型
同样地,通过uid获取wakelock的信息 u.getWakelockStats()
遍历这个map,获取wakeTime次数
wakelock.getWakeTime(BatteryStats.WAKE_TYPE_PARTIAL);
计算总耗时 wakelockTime += timer.getTotalTimeLocked(uSecTime,which);
计算总电量 poewer+=
6
(3)数据通信的消耗
7
(4)wifi运行消耗
8
(5)传感器等等
processMiscUsage()
9
以wifi为例,是所以wifi的电量(wifi使用电量+appwifi使用电量)
addwifiusage()为例子:
long onTimeMs = mStats.getWifiOnTime(uSecNow, mStatsType) / 1000; //获取wifi总时间
long runningTimeMs = mStats.getGlobalWifiRunningTime(uSecNow, mStatsType) / 1000; //获取wifi运行时间
runningTimeMs -= mAppWifiRunning;//这里计算的是非app使用wifi的量(时间)
double wifiPower = (onTimeMs * 0 * mPowerProfile.getAveragePower(PowerProfile.POWERWIFION) + runningTimeMs
* mPowerProfile.getAveragePower(PowerProfile.POWERWIFION)) / 1000;//时间*电量==毫安时
|
|