ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Android 功耗测试

2022-05-30 22:03:51  阅读:255  来源: 互联网

标签:https quot 功耗 耗电 测试 监控 Android android


<head> <title>Evernote Export</title> <basefont face="微软雅黑" size="2" /> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> <meta name="exporter-version" content="YXBJ Windows/605061 (zh-CN, MWS); Windows/10.0.0 (Win64); EDAMVersion=V2;" /> <meta name="reminder-order" content="2022/5/20 1:31" /> <style> body, td { font-family: 微软雅黑; font-size: 10pt; } </style> </head> <body> <a name="792" /> <div> <span> <div> <div> <div> <div> <div>电池</div> <ul> <li> <div>电池容量,电池容量越大手机越笨重</div> </li> <li> <div>充电时间。低电压高电流,高电压低电流</div> </li> <li> <div>寿命</div> </li> <li> <div>安全性</div> </li> </ul> <div>硬件</div> <ul> <li> <div>处理器芯片</div> </li> <ul> <li> <div><span style="font-weight: bold;">CPU</span>,<span style="font-size: unset; color: unset; font-family: unset;">GPU,</span><span style="font-size: unset; color: unset; font-family: unset;">NPU</span></div> </li> </ul> <li> <div>基带芯片</div> </li> <ul> <li> <div><span style="font-weight: bold;">蜂窝网</span>,<span style="font-size: unset; color: unset; font-family: unset;"><span style="font-size: unset; color: unset; font-family: unset; font-weight: bold;">WIFI</span>,</span><span style="font-size: unset; color: unset; font-family: unset;">NFC</span></div> </li> </ul> <li> <div>传感器</div> </li> <ul> <li> <div>加速度传感器,<span style="font-size: unset; color: unset; font-family: unset;">陀螺仪,</span><span style="font-size: unset; color: unset; font-family: unset;">气压计,</span><span style="font-size: unset; color: unset; font-family: unset;">温度传感器</span></div> </li> </ul> <li> <div>外设</div> </li> <ul> <li> <div>相机,<span style="font-size: unset; color: unset; font-family: unset;">麦克风,</span><span style="font-size: unset; color: unset; font-family: unset;">扬声器</span></div> </li> </ul> <li> <div>其他</div> </li> <ul> <li> <div>GPS,<span style="font-size: unset; color: unset; font-family: unset;">内存,</span><span style="font-size: unset; color: unset; font-family: unset;"><span style="font-size: unset; color: unset; font-family: unset; font-weight: bold;">显示屏</span>,</span><span style="font-size: unset; color: unset; font-family: unset;">闪存</span></div> </li> </ul> </ul> <div>资源调度机制是厂商功耗优化的最重要的手段,手机基带,GPS,这些模块在不使用时也会进入低功耗或休眠模式,达到降低功耗的目的。</div> <div>手机厂商为了保证头部应用能有更好的体验,厂商愿意给他们分配更多的资源</div> <div><a href="https://developer.qualcomm.com/software/snapdragon-power-optimization-sdk/quick-start-guide">https://developer.qualcomm.com/software/snapdragon-power-optimization-sdk/quick-start-guide</a> </div> <div><br /></div> <div><span style="font-weight: bold;">软件</span></div> <div><span style="font-weight: bold;">   </span> 如何评估软件的耗电情况: 电能 = 电压 * 电流 * 时间</div> <div>        手机的电压一般恒定,Adnroid 系统要求厂商必须在/frameworks/base/core/res/xml/power_profile.xml提供组件的电源配置文件</div> <div>        如何在不同厂商中获取耗电流</div> <ol> <li> <div>从手机中导出 /system/framework/framework-res.apk 文件</div> </li> <li> <div>使用反编译工具对导出文件framework-res.apk 进行反编译</div> </li> <li> <div>查看power_profile.xml 文件在frame-res 反编译目录路径: /res/xml/power_profile.xml</div> </li> </ol> <div><a href="https://source.android.com/devices/tech/power">https://source.android.com/devices/tech/power</a> </div> <div><a href="https://android.googlesource.com/platform/frameworks/base/+/master/core/res/res/xml/power_profile.xml">https://android.googlesource.com/platform/frameworks/base/+/master/core/res/res/xml/power_profile.xml</a> </div> <div>对于系统的电量消耗情况,可以通过dumpsys   batterystatus 导出</div> <div><br /></div> <div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"> <div>adb shell dumpsys batterystats &gt; battery.txt</div> <div>// 各个Uid的总耗电量,而且是粗略的电量计算估计。</div> <div>Estimated power use (mAh):</div> <div>    Capacity: 3450, Computed drain: 501, actual drain: 552-587</div> <div>    ...</div> <div>    Idle: 41.8</div> <div>    Uid 0: 135 ( cpu=103 wake=31.5 wifi=0.346 )</div> <div>    Uid u0a208: 17.8 ( cpu=17.7 wake=0.00460 wifi=0.0901 )</div> <div>    Uid u0a65: 17.5 ( cpu=12.7 wake=4.11 wifi=0.436 gps=0.309 )</div> <div>    ...</div> <div>// reset电量统计</div> <div>adb shell dumpsys batterystats --reset</div> </div> <div><br /></div> </div> <div> <div><br /></div> <table style="border-collapse: collapse; min-width: 100%;"> <colgroup> <col style="width: 130px;"> </col> <col style="width: 130px;"> </col> <col style="width: 130px;"> </col> <col style="width: 130px;"> </col> <col style="width: 130px;"> </col> </colgroup> <tbody> <tr> <td style="background-color: rgb(115, 115, 115); border: 1px solid rgb(92, 92, 92); width: 130px; padding: 8px;"> <div><span style="color: rgb(255, 255, 255);">编号</span></div> </td> <td style="background-color: rgb(115, 115, 115); border: 1px solid rgb(92, 92, 92); width: 130px; padding: 8px;"> <div>测试方法</div> </td> <td style="background-color: rgb(115, 115, 115); border: 1px solid rgb(92, 92, 92); width: 130px; padding: 8px;"> <div>适用场景</div> </td> <td style="background-color: rgb(115, 115, 115); border: 1px solid rgb(92, 92, 92); width: 130px; padding: 8px;"> <div>优点</div> </td> <td style="background-color: rgb(115, 115, 115); border: 1px solid rgb(92, 92, 92); width: 130px; padding: 8px;"> <div>缺点</div> </td> </tr> <tr> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>1</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>稳压电源+ 电流仪</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>整机电流</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>可以测试整机电流,而且数据精确</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>需要准确硬件工具,测试操作复杂,而且不能准确测试APP消耗电量</div> </td> </tr> <tr> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>2</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;">dumpsys batterystats</td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>App电量</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>有耗电量的详细数据</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>结果可读行比较差</div> </td> </tr> <tr> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>3</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>系统“耗电排行”</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>APP电量</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>直观,跟用户看到的一致</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>没有详细的数据</div> </td> </tr> <tr> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>4</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>Battery History</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>App电量</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>结果直观,有耗电量的详细数据</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>适用与Android 5.0及以上系统</div> </td> </tr> </tbody> </table> <div><a href="https://developer.android.com/studio/debug/bug-report">bug report</a>  <a href="https://github.com/google/battery-historian">Battery Historian </a></div> </div> <div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"> <div><br /></div> <div>//7.0和7.0以后</div> <div>$ adb bugreport bugreport.zip</div> <div>//6.0和6.0之前:</div> <div>$ adb bugreport &gt; bugreport.txt</div> <div>//通过historian图形化展示结果</div> <div>python historian.py -a bugreport.txt &gt; battery.html</div> </div> <div>Android 耗电优化历史</div> <ol start="3"> <li> <div>    野蛮生长: Pre   Android 5.0</div> </li> <ol> <li> <div> 耗电与安装应用程序的数量有关,用户安装越多的应用程序,无论是否打开它们,手机耗电都会很快。</div> </li> <li> <div>App耗电量与APP使用时间无关,<span style="position: absolute;">用户希望 App 的耗电量应该与它的使用时间相关,但是有些应用即使常年不打开,依然非常耗电</span></div> </li> <li> <div><span style="position: absolute;"><span style="font-size: unset; color: unset; font-family: unset;">电量问题排查复杂。无论是电量的测量,还是耗电问题的排查都异常艰难。</span></span> <img src="耗电_files/Image.webp" type="image/webp" data-filename="Image.webp" /><span style="position: absolute;"><span style="font-size: unset; color: unset; font-family: unset;">  </span></span></div> </li> </ol> </ol> <div>逐步收紧:Android 5.0 ~ Android 8.0</div> <div>    <a href="https://developer.android.com/about/versions/android-5.0?hl=zh-cn">https://developer.android.com/about/versions/android-5.0?hl=zh-cn</a> </div> <div><img src="耗电_files/Image [1].webp" type="image/webp" data-filename="Image.webp" /></div> <div>Android 6.0 开始~, Google开始着手清理后台应用和广播来进一步省电</div> <ul> <li> <div>省电模式不够省电</div> </li> <li> <div>用户对应用控制力度不够</div> </li> <li> <div><span style="font-size: unset; color: unset; font-family: unset;"> Target API 开发者响应不积极</span></div> </li> </ul> <div>最严格:Android 9.0</div> </div> <div><br /></div> <div><img src="耗电_files/Image [2].webp" type="image/webp" data-filename="Image.webp" /></div> <hr /> <div>耗电优化与线上监控</div> </div> <div><br /></div> <div>耗电优化</div> <ul> <li> <div>后台耗电(厂商预装项目要求最严格的正是应用后台待机耗电)</div> </li> <ul> <li> <div>用户认为应用的耗电量应该是和使用时间有关的</div> </li> <li> <div>Camera, Audio, Video,Bluetooth, Network, Sensor. Radio, Screen,WiFi, CPU, GPS</div> </li> </ul> <li> <div>符合系统规范,让系统认为你耗电是正常的</div> </li> <ul> <li> <div>Android Vitals</div> </li> </ul> </ul> <div>耗电优化难点</div> <ul> <li> <div>缺乏现场,无法复现</div> </li> <li> <div>信息不全,难以定位</div> </li> <li> <div>无法评估结果</div> </li> </ul> <div>耗电优化的方法</div> <ul> <li> <div>常见的耗电方式</div> </li> <ul> <li> <div>某个需求场景</div> </li> <li> <div>代码的Bug</div> </li> </ul> <li> <div>优化方法</div> </li> <ul> <li> <div>利用厂商通道或定时拉去最新消息</div> </li> </ul> </ul> <div>耗电监控</div> <ol> <li> <div>Android  Vistals</div> </li> <li> <div>耗电监控应该监控什么</div> </li> <ol> <li> <div>监控信息---&gt; 系统关心什么,我们就监控什么(后台耗电监控  )   <span style="position: absolute;">Alarm wakeup、WakeLock、WiFi scans、Network</span></div> </li> <li> <div>现场信息---&gt; 完整的对栈信息</div> </li> <li> <div>提炼规则----&gt;将监控的内容抽象成规则</div> </li> </ol> </ol> <div><br /></div> <div> <div><br /></div> <table style="border-collapse: collapse; min-width: 100%;"> <colgroup> <col style="width: 130px;"> </col> <col style="width: 130px;"> </col> <col style="width: 130px;"> </col> </colgroup> <tbody> <tr> <td style="background-color: rgb(151, 151, 151); border: 1px solid rgb(121, 121, 121); width: 130px; padding: 8px;"> <div><br /></div> </td> <td style="background-color: rgb(151, 151, 151); border: 1px solid rgb(121, 121, 121); width: 130px; padding: 8px;"> <div><span style="color: rgb(255, 255, 255);">前台规则</span></div> </td> <td style="background-color: rgb(151, 151, 151); border: 1px solid rgb(121, 121, 121); width: 130px; padding: 8px;"> <div><span style="color: rgb(255, 255, 255);">后台规则</span></div> </td> </tr> <tr> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>Alarm</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>单个Alarm每小时不能启动超过20次</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>单个Alarm 每小时不能启动超过10次</div> </td> </tr> <tr> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>WakeLock</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>单个WakeLock每小时不能超过30分钟或者超过20次</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <ol> <li> <div>WakeLock每 小时不能超过30分钟;</div> </li> <li> <div>单个WakeLock每小时不能超过10分钟或12次 </div> </li> </ol> </td> </tr> <tr> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>Sensor</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>不监控前台sensor使用</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;">每小时使用不能超过30分钟</td> </tr> <tr> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>WIFI scans</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>每小时扫描不允许超过10次</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>每小时扫描不允许超过4次</div> </td> </tr> <tr> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>Bluetooth scans</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>每小时扫描不能超过10次</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>每小时扫描不允许超过4次</div> </td> </tr> <tr> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>GPS</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>每小时使用不能超过30分钟</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>每小时使用不能超过15分钟</div> </td> </tr> <tr> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>Camera</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>不监控前台相机使用</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;">后台不允许使用相机</td> </tr> <tr> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>Network</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>不监控前台网络耗电</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>每小时后台网络数据量不能超过10MB</div> </td> </tr> <tr> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>CPU</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>不监控前台CPU</div> </td> <td style="width: 130px; padding: 8px; border: 1px solid;"> <div>后台CPU持续超过30分钟</div> </td> </tr> </tbody> </table> <div><br /></div> <div> </div> </div> <div><br /></div> <div><br /></div> <div><span style="font-weight: bold;">如何监控耗电</span></div> <div><span style="font-weight: bold;"> </span></div> <div><span style="font-weight: bold;">Java Hook</span></div> <div><br /></div> <div>    WakeLock</div> <div>    <a href="https://androidxref.com/7.0.0_r1/xref/frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java">https://androidxref.com/7.0.0_r1/xref/frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java</a> </div> <div>    <a href="https://developer.android.com/training/scheduling/wakelock">https://developer.android.com/training/scheduling/wakelock</a> </div> <div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"> <div>// 代理PowerManagerService</div> <div>ProxyHook().proxyHook(context.getSystemService(Context.POWER_SERVICE), &quot;mService&quot;, this);</div> <div>@Override</div> <div>public void beforeInvoke(Method method, Object[] args) {</div> <div>    // 申请Wakelock</div> <div>    if (method.getName().equals(&quot;acquireWakeLock&quot;)) {</div> <div>        if (isAppBackground()) {</div> <div>            // 应用后台逻辑,获取应用堆栈等等     </div> <div>         } else {</div> <div>            // 应用前台逻辑,获取应用堆栈等等</div> <div>         }</div> <div>    // 释放Wakelock</div> <div>    } else if (method.getName().equals(&quot;releaseWakeLock&quot;)) {</div> <div>       // 释放的逻辑    </div> <div>    }</div> <div>}</div> </div> <div>Alarm : 用来执行定时的重复任务</div> <ul> <li> <div><a href="https://developer.android.com/training/scheduling/alarms">https://developer.android.com/training/scheduling/alarms</a> </div> </li> <li> <div><a href="https://developer.android.com/reference/android/app/AlarmManager.html#ELAPSED_REALTIME_WAKEUP">https://developer.android.com/reference/android/app/AlarmManager.html#ELAPSED_REALTIME_WAKEUP</a> </div> </li> <li> <div><a href="https://developer.android.com/reference/android/app/AlarmManager.html#RTC_WAKEUP">https://developer.android.com/reference/android/app/AlarmManager.html#RTC_WAKEUP</a> </div> </li> </ul> <div><br /></div> <div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"> <div><br /></div> <div><br /></div> <div>// 代理AlarmManagerService</div> <div>new ProxyHook().proxyHook(context.getSystemService</div> <div>(Context.ALARM_SERVICE), &quot;mService&quot;, this);</div> <div><br /></div> <div><br /></div> <div>public void beforeInvoke(Method method, Object[] args) {</div> <div>    // 设置Alarm</div> <div>    if (method.getName().equals(&quot;set&quot;)) {</div> <div>        // 不同版本参数类型的适配,获取应用堆栈等等</div> <div>    // 清除Alarm</div> <div>    } else if (method.getName().equals(&quot;remove&quot;)) {</div> <div>        // 清除的逻辑</div> <div>    }</div> <div>}</div> </div> <hr /> <div><span style="font-size: unset; color: unset; font-family: unset;">后台CPU</span></div> <div><span style="position: absolute;">对于 GPS 监控,我们可以通过 Hook 代理LOCATION_SERVICE。对于 Sensor,我们通过 Hook SENSOR_SERVICE中的“mSensorListeners”</span></div> <div><span style="font-size: unset;"><br /></span></div> <div><span style="position: absolute;">通过 Hook,我们可以在申请资源的时候将堆栈信息保存起来。当我们触发某个规则上报问题的时候,可以将收集到的堆栈信息、电池是否充电、CPU 信息、应用前后台时间等辅助信息也一起带上</span></div> <div><br /></div> <div><br /></div> <div><br /></div> <div><br /></div> <div><br /></div> <div><br /></div> <div><br /></div> <div><br /></div> <div><span style="font-weight: bold;">插桩</span></div> <div><br /></div> <div><span style="position: absolute;">写一个基础类,然后在统一的调用接口中增加监控逻辑。以 WakeLock 为例:</span></div> <div><br /></div> <div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"> <div><br /></div> <div>public class WakelockMetrics {</div> <div>    // Wakelock 申请</div> <div>    public void acquire(PowerManager.WakeLock wakelock) {</div> <div>        wakeLock.acquire();</div> <div>        // 在这里增加Wakelock 申请监控逻辑</div> <div>    }</div> <div>    // Wakelock 释放</div> <div>    public void release(PowerManager.WakeLock wakelock, int flags) {</div> <div>        wakelock.release();</div> <div>        // 在这里增加Wakelock 释放监控逻辑</div> <div>    }</div> <div>}</div> </div> <div><br /></div> <div><a href="https://blog.dreamtobe.cn/2016/08/15/android_scheduler_and_battery/">https://blog.dreamtobe.cn/2016/08/15/android_scheduler_and_battery/</a> </div> <div><br /></div> <div><br /></div> <hr /> <div>CTS 测试  :<a href="https://source.android.google.cn/compatibility/cts/run">https://source.android.google.cn/compatibility/cts/run</a> </div> <hr /> <div><br /></div> </div> <div><br /></div> </span> </div> </body>

标签:https,quot,功耗,耗电,测试,监控,Android,android
来源: https://www.cnblogs.com/stormliu/p/16291235.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有