Android 作为优秀的移动系统,为用户提供了完美的个性化体验,Android强大的功能都是以持久可靠稳定的电量为基础的。各个手机大厂,也十分重视电源管理这块,纷纷引入了不同的电量优化行为。于是,开发者需要面对一个问题,如何合理的在不同设备上进行后台操作。Android 系统也在解决这样的难题,通过提供更高效的电量优化功能,来平衡各个大厂对电量持久的期望,同时也满足开发者对后台运行的合理需求。
最近 几个Android 版本所带来的电量优化功能:
Android Lolilop 系统: 提供了Job Scheduler 进行后台任务的管理,这个API基本是将后台任务,按照 减少运行次数,延迟到合理环境的思想去管理你的后台任务,同时也提供了一个电源历史数据分析工具。Battery Historian
Androd Marshmallow 和 Nougat 的时候,电量管理推出了 Doze低电量模式(根据设备使用状态活跃与否),Doze被触发后,系统会对应用程序的后台运行施加限制。
Android Oreo 的时候 ,进行了后台执行的限制(后台服务限制,隐式意图广播限制),以及后台位置服务的限制。在O上,隐式意图的广播,会不再被相应,屏幕关闭后,后台位置服务也会被限制。当然, 我们这儿的流氓软件,都不care这些事。
Android pie 的时候,电量进行了优化限制的规则大致如下:
App standby Buckets 应用分组 :
第一 :根据用户应用的使用情况,进行分组,然后对不同的分组加以不同程度的后台限制。(这一策略是,因为手机装的应用多,但是用户使用的核心App 可能就是十几个,那么不常使用的App,不应该消耗电源,第二,应用安装多了,用户可能使用了若干个APP,但是使用App的时间,并没有太多的变化,耗电量不应该和应用安装数量成正相关)
使用 应用待机分组,使应用程序的用电量和使用程度相关,而非安装数量。
Active 活跃组 Working Set 工作组 Frequent 常用组 Rare少用组
第二: 对一些后台不合理运行的应用程序,系统为用户提供了限制的操作,也就是电池设置里的“后台限制功能”。当然,我也在有些手机上看到手机卫士对应用高耗电的提示。
第三,在之前的省电模式上进行进一步的优化了。
那么 开发者,可能面对的就是,你写的App 在不同的时间段,都可能被系统规划到不同的分组,所处的分组不同,后台限制
就会不同。使用adb 命令来模拟应用分组:
命令行:
获得standby分组:
adb shell dumpsys battery unplug
adb shell am get -standby-bucket <package name>
10 ACTIVE
20 WORKING_SET
30 FREQUENT
40 RARE
设置 standby 分组
adb shell am set-standby-bucket <package name>
并且测试重要的通知是否发送。
代码中可以使用
API UsageStateManager.getAppStandbyBucket();
对于Android 后台限制功能模拟:使用adb命令来模拟这一个过程:
adb shell appops set <package name> RUN_ANY_IN_BACKGROUND ignore
取消background restriction限制:
测试省电模式:
adb shell dumpsys battery unplug
adb shell settings put global low_power 1
你的测试用例:
adb shell dumpsys battery reset
获取设备状态:
PowerManager.isPowerSaveMode()
PowerManager.ACTION_POWER_SAVE_MODE_CHANGED
作为开发者,应该从这三方面依次去测试和优化你的App,并且再做这些操作的时候,应该设置你App的targetSDK 版本大于26
1 首先是查看设备状态:设备可能处于Doze状态:
2 接着是检查用户操作: 是否是省电模式开启, 是否应用被加入了后台限制
3 应用程序的使用情况: 因为pie系统中,应用待机分组功能,会对应用程序进行不同成都的后台限制。
当然作为系统App开发者,开发者应使用adb 命令执行省电模式,来测试你的应用,
开启省电模式
adb shell appops set <package name> RUN_ANY_IN_BACKGROUND allow
查看运行状态:
dumpsys jobscheduler
dumpsys alarm
在写代码的时候,也应该考虑业务需求和后台业务的设计,将不是很重要的任务按照 “减少,延迟,合并“的思路,去设计,当然了,实际工作中,还是看看自己的开发时长,嘿嘿。
减少不必要的后台运行,延迟到手机充电或者WiFi模式下,合并后台操作。当然也可以,开启一个前台服务,用来执行用户即将做什么操作,因为前台服务优先级比较高的嘛,使用API :startForegroundService()。在oreo上,如果后天服务的使用好像还要限制,10秒内,不启动前台服务,会异常。使用前台 服务,同时需要发送一个Notification到SystemUI上。
当然最好学习下下或了解下这2个工具Energy Profiler(Android studio3.2 +) , Android Vitals.
补充: 低电耗模式:
如果用户未插接设备的电源,在屏幕关闭的情况下,让设备在一段时间内保持不活动状态,那么设备就会进入低电耗模式。在低电耗模式下,系统会尝试通过限制应用访问占用大量网络和 CPU 资源的服务来节省电量。它还会阻止应用访问网络,并延迟其作业、同步和标准闹钟。
系统会定期退出低电耗模式一小段时间,让应用完成其延迟的活动。在此维护期内,系统会运行所有待处理的同步、作业和闹钟,并允许应用访问网络。
图 1. 低电耗模式提供了周期性维护期,让应用使用网络并处理待处理的活动。
在每个维护期结束时,系统会再次进入低电耗模式,暂停网络访问并推迟作业、同步和闹钟。随着时间的推移,系统安排维护期的次数越来越少,这有助于在设备未连接至充电器的情况下长期处于不活动状态时降低耗电量。
一旦用户通过移动设备、打开屏幕或连接至充电器唤醒设备,系统就会立即退出低电耗模式,并且所有应用都会恢复正常活动。
用于后台执行任务的Api:
Loader, JobServie,WorkManager等等。
参考资料:
https://developer.android.google.cn/topic/performance/vitals/index.html