Android电量优化全解析
原文: https://www.jianshu.com/p/c86021fe958d
如何进行电量优化?
了解手机关键耗电的地方及分析耗电的工具后。接下来就是我们的核心,如何来进行电量的优 化?首先我们先简单总结汇总一下耗电的相关因素
- 屏幕亮暗相关
- 设备 awake,sleep 的切换,尤其是唤醒.
- CPU 运行相关
- 网络
- 传感器
我们都知道屏幕的渲染及 CPU 的运行是耗电的主要因素之一。所以当我们在做内存优化、渲染优化、计算优化的时候,就已然在做电量优化。所以在平时的开发中,我们要注意点滴性能 的优化积累,实际上当我们来做电量分析的时候,也是在找自己挖的坑。所以尽量有意识在项 目的开发过程中尽量少挖坑,这一点是我们在分析其他优化项首先要提到的一个点。
监听手机充电状态
我们可以通过下面的代码来获取手机的当前充电状态:
这里我们就需要思考,根据具体的业务,考虑将一些不需要及时地和用户交互的操作放到充电 的时候去做。比如:360 手机助手,当充上电的时候,才会自动清理手机垃圾,自动备份上传图片、联系人 等到云端,从而避免当用户手机低电量时,任然继续进行耗电操作。
屏幕唤醒
当 Android 设备空闲时,屏幕会变暗,然后关闭屏幕,最后会停止 CPU 的运行,这样可以防 止电池电量掉的快。但有些时候我们需要改变 Android 系统默认的这种状态:比如玩游戏时我 们需要保持屏幕常亮,比如一些下载操作不需要屏幕常亮但需要 CPU 一直运行直到任务完成。
保持屏幕常亮比较好的方式是在 Activity 中使用 FLAG_KEEP_SCREEN_ON 的 Flag。
这个方法的好处是不像唤醒锁(wake locks),需要一些特定的权限(permission)。并且能 正确管理不同 app 之间的切换,不用担心无用资源的释放问题。
另一个方式是在布局文件中使用 android:keepScreenOn 属性:
android:keepScreenOn = “true”的作用和 FLAG_KEEP_SCREEN_ON 一样,使用代码的好 处是你允许你在需要的地方关闭屏幕。
注意:一般不需要人为的去掉 FLAG_KEEP_SCREEN_ON 的 flag,windowManager 会管理好程序进入 后台回到前台的的操作。如果确实需要手动清掉常亮的 flag,使用
所以这里我们需要根据自己的 APP 实际情况,根据业务来控制好是否保持屏幕常量。比如 APP 需要支持视频播放。那么在播放的界面需要控制好不熄屏,当退出播放时,当然就没有了 这个设置。
WakeLock
wake_lock 锁主要是相对系统的休眠而言的,意思就是程序给 CPU 加了这个锁那系统就不会 休眠了,这样做的目的是为了全力配合我们程序的运行。有的情况如果不这么做就会出现一些 问题。
需要使用 PowerManager 这个系统服务的唤醒锁(wake locks)特征来保持 CPU 处于唤醒状 态。唤醒锁允许程序控制宿主设备的电量状态,创建和持有唤醒锁对电池的续航有较大的影 响,所以,除非是真的需要唤醒锁完成尽可能短的时间在后台完成的任务时才使用它。比如在 Acitivity 中就没必要用了。如果需要关闭屏幕,使用上述的 FLAG_KEEP_SCREEN_ON。
只有一种合理的使用场景,使用后台服务在屏幕关闭情况下 hold 住 CPU 完成一些工作,需要 使用唤醒锁,如果不使用唤醒锁来执行后台服务,不能保证因 CPU 休眠未来的某个时刻任务 会停止,这不是我们想要的。
唤醒锁可划分并识别为四种用户唤醒锁:
标记值 | CPU | 屏幕 | 键盘 |
---|---|---|---|
PARTIAL_WAKE_LOCK | 开启 | 关闭 | 关闭 |
SCREEN_DIM_WAKE_LOCK | 开启 | 变暗 | 关闭 |
SCREEN_BRIGHT_WAKE_LOCK | 开启 | 变亮 | 关闭 |
FULL_WAKE_LOCK | 开启 | 变亮 | 变亮 |
注意:自 API 等级 17 开始,FULL_WAKE_LOCK 将被弃用。 应用应使用 FLAG_KEEP_SCREEN_ON。
1.添加唤醒锁权限:
2.直接使用唤醒锁:
JobScheduler
自 Android 5.0 发布以来,JobScheduler 已成为执行后台工作的很好的方式,其工作方式有 利于用户在适当的时机执行正确的事情。应用可以在安排作业的同时允许系统基于内存、电源 和连接情况进行优化。JobSchedule 的宗旨就是把一些不是特别紧急的任务放到更合适的时机 批量处理。这样做有两个好处:
- 避免频繁的唤醒硬件模块,造成不必要的电量消耗。
- 避免在不合适的时间(例如低电量情况下、弱网络或者移动网络情况下的)执行过多的
任务消耗电量。
GPS
选择合适的 Location Provider
Android 系统支持多个 Location Provider:
- GPS_PROVIDER: GPS 定位,利用 GPS 芯片通过卫星获得自己的位置信息。定位精准度高,一般在 10 米左右, 耗电量大;但是在室内,GPS 定位基本没用。
-
NETWORK_PROVIDER: 网络定位,利用手机基站和 WIFI 节点的地址来大致定位位置,这种定位方式取决于服务器,
即取决于将基站或 WIF 节点信息翻译成位置信息的服务器的能力。 - PASSIVE_PROVIDER: 被动定位,就是用现成的,当其他应用使用定位更新了定位信息,系统会保存下来,该应用接 收到消息后直接读取就可以了。
如果 App 只是需要一个粗略的定位那么就不需要使用 GPS 进行定位,既耗费电量,定位的耗时也久。
及时注销定位监听
在获取到定位之后或者程序处于后台时,注销定位监听,此时监听 GPS 传感器相当于执行 no- op(无操作指令),用户不会有感知但是却耗电。
多模块使用定位尽量复用
多个模块使用定位,尽量复用上一次的结果,而不是都重新走定位的过程,节省电量损耗;例 如:在应用启动的时候获取一次定位,保存结果,之后再用到定位的地方都直接去取。
传感器
使用传感器,选择合适的采样率,越高的采样率类型则越费电。
- SENSOR_DELAY_NOMAL (200000 微秒)
- SENSOR_DELAY_UI (60000 微秒)
- SENSOR_DELAY_GAME (20000 微秒)
- SENSOR_DELAY_FASTEST (0 微秒)
在后台时注意及时注销传感器监听。
Doze and App Standby
最后提这一点,理论上不是电量优化,而是做电量优化要注意的一个坑。Doze and App Standby 是 Android 6.0 以后,提供了两种省电延长电池寿命的功能。
具体可参考 google 官方介绍文档。
参考资料:https://github.com/google/battery-historian#wakelock-analysis