Android 电量优化
本文链接:https://blog.csdn.net/feather_wch/article/details/131648478
基本概念
1、手机耗电的元凶?
- 软件
- 硬件,功率计
2、App三大耗电模块
- 显示
- 网络
- CPU
3、电能公式
电能J = 电功率P * 时间t
电功率P = 电压U * 电流I
电量Q = 电流I * 时间t
4、电池容量是什么?
电池容量4000mah: 以4000ma放电可以放1h
如何测试耗电量
5、测试耗电量有哪些方法?
- Android API:registerReceiver(receiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED))
- 读取系统电池传感器设备节点:?/sys/class/power_supply_battery/uevent
- 使用外置电流仪器
原因分析
6、Android能耗统计文件
- 放置在
frameworks/base/core/res/res/xml/power_profile.xml
- 每个手机都有framworks-res.apk 反编译后,可以找到
res/xml/power_profile.xml
- 不同厂商的不同设备,都有不同,取决于硬件。最终电量计算来源于该xml
//power_profile 内容如下
<?xml version="1.0" encoding="utf-8"?>
<device name="Android">
<item name="ambient.on">0.1</item> <!-- ~100mA -->
<item name="screen.on">0.1</item> <!-- ~100mA -->
<item name="screen.full">0.1</item> <!-- ~100mA -->
<item name="bluetooth.active">0.1</item> <!-- Bluetooth data transfer, ~10mA -->
<item name="bluetooth.on">0.1</item> <!-- Bluetooth on & connectable, but not connected, ~0.1mA -->
<item name="wifi.on">0.1</item> <!-- ~3mA -->
<item name="wifi.active">0.1</item> <!-- WIFI data transfer, ~200mA -->
<item name="wifi.scan">0.1</item> <!-- WIFI network scanning, ~100mA -->
<item name="audio">0.1</item> <!-- ~10mA -->
<item name="video">0.1</item> <!-- ~50mA -->
<item name="camera.flashlight">0.1</item> <!-- Avg. power for camera flash, ~160mA -->
<item name="camera.avg">0.1</item> <!-- Avg. power use of camera in standard usecases, ~550mA -->
<item name="gps.on">0.1</item> <!-- ~50mA -->
//省略很多..............
</device>
7、BatteryStatsHelper.java 帮助进行电量消耗计算,位于BatteryStatsService.java服务中
- 源码中可以看到通话、数据、wifi、传感器等所有功能的耗电量
- 移动网络虚弱的时候,需要停止网络请求 ==> 耗电量是每个信号强度耗电量累加
8、应用程序的耗电量计算是按照uid统计的
- 如果通过shareuid都加入到同一个uid中,那么电量消耗是算在一起的
9、WakeLock耗电量
- 进程wakelock事件 * cpu_awake(power_profile.xml中ccpu_awake)
10、WakeLock是什么?
- 有些App功能需要熄屏时还可以继续工作,比如音乐
- wakelock机制能让app继续运行
- 注意一定要及时释放:会导致耗电量统计非常大
电能统计
11、电能统计-重置+开启
- adb shell dumpsys batterystats --reset
- adb shell dumpsys --enable full-wake-history
- adb shell dumpsys --disable full-wake-history
12、电能统计-直接查看分析
- adb shell dumpsys batterystats --charge
13、电能统计-文本分析
- adb shell dumpsys batterystats > batterystats.txt
- adb shell dumpsys batterystats > com.xx.xxx > batterystats.txt
14、batterystats.txt分析:对实际优化有哪些帮助?
- 看到网络耗电量很大,需要关注网络请求部分,网络切换部分
15、AlramManager闹钟唤醒所持有的锁不合理,也会导致耗电量多
16、RIJ:通信上层需要向Modem(调制解调器)发送数据时,此时会获取名为RIJ 的锁
17、应用锁是什么?
18、JobScheduler调度的任务所持有的锁
- 可以看到淘宝有使用这个JobScheduler
19、分析各种复杂系统日志的技巧
- 先锁定时间点
- 再搜索关键字
BatteryHistorian
20、BatteryHistorian环境搭建有两种方式
- Docker + 镜像
- GoLang + Python2.7 + Git + Java + 拉取源代码 + 编译
21、电能统计-Battery Historian 2.0 分析
- adb bugreport xxx_bugreport.zip
- zip上传至 http://localhost:9999
- 上传成功会显示图形化页面
实战
显示屏
22、OLED屏幕 => 深色会比浅色更省电
- 通过开关控制深色
- 使用的时候建议亮度最大。如果是80%的亮度,就是开80%的时间,关80%的时间
23、LCD => 影响功耗的只有亮度
- 底层有个发光模块,去照射中间的颜色层。
- 亮度越高,耗电越大
24、显示优化方案
- 不影响应用场景的情况下,尽量使用深色主题
网络
25、网络的影响
- 大部分耗电都和网络有关
- 尤其是弱网场景下:网络差时进入偏向状态,以最大功率获取信号
26、3G模式下状态机,新建一次请求消耗多少电量?
- 一共20s电量消耗:(总结在三种状态中切换)
- 从
Low Power
1.5s后进入最佳状态Full Power
- 5s后进入
Low Power
- 12s后进入
Standby
27、4G下RRC状态机 4G(LTE)状态机
- 尽量合并网络请求,减少状态机切换
28、Wifi优化
- Wifi状态下尽量把数据都请求了
- 通常情况wifi功耗低于移动网络
- 有时候Wifi很卡不是因为别人用了Wifi,而是不同wifi频率相同,共享了带宽
29、GPS优化
- GPS使用时开启,不用时关闭
- 使用时要检测GPS信号强度,强度很弱会增加功耗和发热
30、网络优化总结
- 增量拉取数据
- 界面展示的数据非wifi下不预先取
- 实时信息上报在后台时改成非实时
- 合并网络请求,减少请求次数
- 尽量利用wifi请求数据
- 有功能需要频繁拉取网络信息,非wifi情况下不要那么频繁
CPU
31、CPU时间片是什么
- 计算机中每相隔N个高电频脉冲,时钟计数器+1,自然分割成小块
- 时间片,10ms,单位jiffies(1/Hz)内核时钟单位
32、变频
- CPU根据需求有多重变频方案:快升快降,慢升快降,快升慢降
33、CPU利用率越高越耗电? => 错误的,CPU功耗只和频率有关。
34、CPU优化方案总结
- 计算优化
- 避免浮点
- 除法变乘法
- 利用位移
- 查表法:使用映射关系,但会增加内存
- 用arm neon指令集做并行运算
- 避免WakeLock使用不当:根据需求选择CPU运转+是否屏幕常亮+是否有键盘灯
- 避免AlarmManager使用不当:能不用就不用,选择好策略(是否唤醒设备)
- 使用Job Scheduler(WorkManager)
- 定时数据库更新和上报
- 充电时才需要执行备份数据
- Wifi预加载数据
- 可以批量执行任务
35、Doze模式
- 判断用户连续一段时间没有使用手机,延缓App中后台的CPU和网络活动
总结
36、设计和编码时如何进行电量优化(避免)
- 阻止手机休眠
- 经常唤醒手机
- 后台频繁运行
- 过度绘制
37、WakeLock使用
WakeLock wakelock = powerManager.newWakeLock(xxx);
wakelock.acquire();
...
if(wakelock.isHeld()){
wakelock.release();
}
wakelock.acquire(timeout) // 可以多少毫秒后,自动释放
wakelock.setRefrenceCounted(false) // 可以直接关闭引用计数,一次release就直接完全释放
- WakeLock适合熄屏后还要执行的任务(音乐)
- WakeLock acquire和release要配对使用,一一对应
- WakeLock 只支持Service组件使用
- 使用Partial WakeLock需要设定timeout,超过时间后自动释放。避免无法释放导致问题。
38、Alarm使用
- 场合:App进程不存在了,也需要在某短时间在后台做事(闹钟、记事提醒、给服务器上传数据)
- 耗电元凶
39、广播
- 尽量不要使用常驻静态广播
- 关闭广播:
- 使用时开启,使用完关闭:pm.setComponentEnableSetting(receiver,…)
- 尽量注册动态广播
- 尽量避免注册有序广播
- 用LocalBroadcastManager(Handler实现,同进程广播)
- 用包名去限定广播接收的范围
- 跨进程频繁通信:要使用bindService或者ContentResolver.call
40、Activity pause释放/暂停不必要资源文章来源:https://www.toymoban.com/news/detail-547235.html
- 位置更新
- 传感器
- 动画、滑动 停止
- unregister一些资源,如果不能unregister就设置flag标志,到前台时才真正更新数据
- 减少View的background
41、网络报错处理文章来源地址https://www.toymoban.com/news/detail-547235.html
- 优先检测网络是否联通
- 增加失败重试机制,重试次数越多,间隔时间越长
到了这里,关于Android 电量优化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!