(点击上方公众号,可快速关注)
来源:龚振杰
https://blog.dreamtobe.cn/2016/08/15/android_scheduler_and_battery/
如有好文章投稿,请点击 → 这里了解详情
I. Handler:
在进程存活的期间有效使用, Google官方推荐使用。
相关机制可以参见: Android Handler Looper机制
II. AlarmManager:
利用系统层级的闹钟服务(持有Wake Lock)。
1. 使用场景
在大概的时间间隔(重复)运行指定任务。
在精确的时间间隔(重复)运行指定任务。
2. 特征
运行在系统的闹钟服务上的,注册以后,无论是自己的应用进程或组件是否存在,都会正常运作。
所有注册的闹钟服务都会在系统重启后复位,因此如果需要保证任务,就需要注册RECEIVE_BOOT_COMPLETE广播,确保重启后,可以重新将任务注册到闹钟服务中。
AlarmManager处理的是一个PendingIntent。
考虑到电量损耗,建议非特殊情况使用大概时间间隔的规则,这样Android会尽量让几个任务打包在一起执行,防止频繁的唤起手机。
III. Job Scheduler:
JobScheduler官方文档
1. 使用场景
在指定特定场景下执行指定任务
2. 特征
Job Scheduler只有在Api21或以上的系统支持。
Job Scheduler是将多个任务打包在一个场景下执行。
在系统重启以后,任务会依然保留在Job Scheduler当中,因此不需要监听系统启动状态重复设定。
如果在一定期限内还没有满足特定执行所需情况,Job Scheduler会将这些任务加入队列,并且随后会进行执行。
3. 接口类型
boolean onStartJob(JobParams params) {
// 开始执行
// 注意这个方法是在主线程执行的,如果是耗时操作请抛到独立线程中
// jobFinished(JobParameters params) // 在完成任务并且决定是否还需要定时执行更多任务
// return 是否是在独立现在还有事务要执行
}
void onStopJob(){
// 用于清理数据,在结束任务后被回调。
}
IV. GCM(FCM)
GCM Network Manager实际上在 Api 21 或以上也是使用了 Job Scheduler,在此之前的版本使用的是Google Play Service中实现Job Scheduler的功能。
在GCMNetworkManager中有很多利于省电的规则。
在中国内地,该服务被墙,无法正常使用。
1. 使用场景
2. 特征
系统级别维护的长链接,十分稳定。
3. 接口类型
V. Sync Adapter
Transferring Data Using Sync Adapters
1. 使用场景
用于同步服务端与本地设备中的数据。
2. 特征
省电稳定。
可绑定一个账户。
利于大数据同步。
通过提供ContentProvider,可以快捷的与服务端同步的数据库。
只有在存在网络的时候才触发同步。
不需要依赖Google Play Service。
用户可以通过设置中主动查看同步的时间,以及触发同步,或者关闭同步。
Sync Adapter在API7或以上就可以使用,因此在一些场景下这是Job Scheduler在API21之前比较好的替代品。
3. 在一定的场景下触发同步
尽可能的打包所有需要同步的任务在一个周期中执行,以此来进行尽可能的节省手机电量。
VI. Doze Mode
Deep Doze Mode
API23中直接称其为Doze Mode。
1. 特征
旨在: 在用户离开设备以后,尽可能的减少手机电量的消耗。
所有任务周期通过移动窗口打包任务执行,并且间隔时间会越来越久。
2. 进入条件
会同时满足以下情况一段时间(大约30分钟)以后生效:
退出条件是,进入条件中任意条件状态发生变化。
3. 在两个处理窗口之间的手机状态
对所有应用拒绝网络访问。
所有JobScheduler、Sync-Adapter、AlarmManager的任务都会被延后到窗口中执行。
系统会拒绝所有来自应用的Wake Lock
停止所有Wifi以及GPS扫描
减少位置事件从设备检测WiFi热点。
Light Doze Mode
Android 7或以上会启用该模式。
1. 特征
2. 进入条件
会同时满足以下情况一段时间(大约几分钟)以后生效:
或者在Deep Doze Mode的情况下同时满足以下条件下生效:
3. 退出条件
屏幕打开
手机开始充电
进入Deep Doze Mode
4. 在两个处理窗口之间的手机状态
中断/避开Doze
以下所有情况,Google官方都建议不在特殊情景,不要去使用,由于中断了Doze Mode的省电规则。
1. AlarmManager
在精确的时间间隔中运行的任务: setAndAllowWhileIdle()、setExactAndAllowWhileIdle()。但是在非窗口期间并不解除无网络访问的限制,并且只有10s的时间给予处理。
指定闹钟事件AlarmManager.setAlarmClock()的事件会在闹钟结束前,令系统短暂的完全退出Doze模式,并且正常处理事件,系统为了突显该闹钟事件,将会在系统的Status Bar上显示物理闹钟的ICON。
2. FCM/GCM
(Firebase Cloud Messaging,旧版中称为Google Cloud Messaging(GCM))。
FCM/GCM中高优先级的任务配置中("priority" : "high") 的消息,在Doze模式下可以正常及时到达。
3. 白名单
白名单官方文档
官方建议可考虑加入白名单的情况
主动请求加入白名单,用户同意以后才加入白名单;
用户也可以主动将应用从白名单中删除或将应用添加到白名单中;
应用可以通过isIgnoringBatteryOptimizations()来获知是否在白名单中;
白名单的应用可以访问网络与持有有效的Wake Lock,但是其他Doze的约束依然存在(如延后的Job Scheduler、Syncs-Adapter、AlarmManager);
白名单的请求方式:
通过ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS打开电量优化页面,用户可以通过搜索来关闭应用的电量优化,以此加入白名单。
先持有REQUEST_IGNORE_BATTERY_OPTIMIZATIONS权限,然后通过启动IntentACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS直接弹出Dialog让用户关闭应用的电量优化,以此加入白名单。
4. 特殊情况
前台服务(Foreground Service)将不会受到Doze模式影响。
Doze模式测试
Google官方提供了一些adb命令用于测试Doze模式,而非需要通过等待来进入Doze模式的。
1. 进入Doze模式
准备一台系统是在Android Nougat Developer Preview4或以上版本的设备。
将其连接连接到电脑。
通过执行adb shell dumpsys battery unplug命令让设备进入未连接充电的模式。
通过执行adb shell dumpsys deviceidle step [light|deep]强行进入Doze模式。
退出Doze模式,让手机恢复正常需要复位充电模式:adb shell dumpsys battery reset。
2. 其他指令
在Android Nougat Developer Preview 4中,Doze模式的状态周期是:
Light: ACTIVE -> IDLE -> IDLE_MAINTENANCE -> OVERRIDE
Deep: ACTIVE -> IDLE_PENDING -> SENSING -> LOCATING -> IDLE -> IDLE_MAINTENANCE
看完本文有收获?请分享给更多人
关注「安卓开发精选」,提升安卓开发技术