51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 5223|回复: 1
打印 上一主题 下一主题

【我分享】[Android]电量优化之app算法

[复制链接]
  • TA的每日心情
    慵懒
    2017-7-9 10:38
  • 签到天数: 13 天

    连续签到: 1 天

    [LV.3]测试连长

    跳转到指定楼层
    1#
    发表于 2015-1-8 08:34:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    针对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;//时间*电量==毫安时

    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-16 16:38 , Processed in 0.063016 second(s), 23 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表