= :startingAt AND state IN COMPLETED_STATES ORDER BY last_enqueue_time DESC")fun getRecentlyCompletedWork。社区说|浅谈 WorkManager 的设计与实现:系统概述( 四 )。" />

社区说|浅谈 WorkManager 的设计与实现:系统概述( 四 )

// 获取全部近期已完成的任务@Query("SELECT * FROM workspec WHERE last_enqueue_time >= :startingAt AND state IN COMPLETED_STATES ORDER BY last_enqueue_time DESC")fun getRecentlyCompletedWork(startingAt: Long): List// ...}
这可称之额外收获,通过 Room 的持久化存储,在保证了任务能够被稳定执行的同时,还可对所有任务进行备份,从而向开发者提供更多额外的能力 。
准确来说, 内部的 Dao 提供了方法,但并未直接暴露给开发者,而是用于内部解决 任务间的冲突 问题,这个后文再提 。
优先级管理
下面我们针对任务的 优先级 进一步进行讨论 。
虽然上文明确说了,对于需要立即执行的行为,不应该作为后台任务,而是应该直接执行对应的业务代码块——看起来优先级机制并非刚需 。
但实际上,这种机制仍然有一定的必要性 。
1.约束条件
说到 约束条件,熟悉的开发者对此不会感到陌生,
约束条件概念
约束运行工作所需的网络类型 。例如 Wi-Fi () 。
如果设置为 true,那么当设备处于“电量不足模式”时,工作不会运行 。
如果设置为 true,那么工作只能在设备充电时运行 。
如果设置为 true,则要求用户的设备必须处于空闲状态,才能运行工作 。在运行批量操作时,此约束会非常有用;若是不用此约束,批量操作可能会降低用户设备上正在积极运行的其他应用的性能 。
如果设置为 true,那么当用户设备上的存储空间不足时,工作不会运行 。
也提供了类似的概念,实际上内部也正是基于实现的,但并非只是单纯的代理 。
首先,当API版本不足时, 兼容性使用或作为补充:
// androidx.work.impl.Schedulers.javastatic Scheduler createBestAvailableBackgroundScheduler(@NonNull Context context,@NonNull WorkManagerImpl workManager) {Scheduler scheduler;if (Build.VERSION.SDK_INT >= WorkManagerImpl.MIN_JOB_SCHEDULER_API_LEVEL) {scheduler = new SystemJobScheduler(context, workManager);} else {scheduler = tryCreateGcmBasedScheduler(context);if (scheduler == null) {scheduler = new SystemAlarmScheduler(context);}}return scheduler;}
其次,读者知道, 的等回调默认运行在主线程,不能直接进行耗时操作 。的内部则进行了线程调度,默认实现在 :
// androidx.work.impl.background.systemjob.SystemJobServicepublic class SystemJobService extends JobService {public boolean onStartJob(@NonNull JobParameters params) {//...mWorkManagerImpl.startWork(...);}}// androidx.work.impl.WorkManagerImplpublic class WorkManagerImpl extends WorkManager {public void startWork(...) {mWorkTaskExecutor.executeOnTaskThread(new StartWorkRunnable(...));}}
由于是由系统服务中的实现的,因此其自身的高权限,可以在APP被杀或重启后,仍然可以唤起并执行及对应的任务 。
2.新的保活机制?
官方提供了后台作业的强大支持,国内厂商大多数第一时间却想拿它来做 保活 。
——举例来说,既然支持定期任务,且即使 APP 被杀或者重启都能够保证执行;那么我一个 IM APP,每 10 秒拉取下接口看有没有新消息,顺便启动下 APP 某些页面或者通知组件,想必也是非常合理的 。
实际上,对于 保活 的诉求, 做不到,其本质是做不到:
首先,随着版本的迭代, 系统对后台任务的管理愈发严苛,小于 15 分钟的定期任务已经被强制调整为 15 分钟执行,避免频繁的后台定时任务对前台应用的影响,规避了 API 的非法滥用:
: 我把你当兄弟,你竟然想睡我?
其次是笔者的猜测,由于用户安全等相关的考量,国内设备厂商对等相关都有一定的魔改——比如,当用户手动将 APP 强制关闭,这种操作意图拥有最高优先级,即使是系统服务也不应对其再次启动(厂商白名单除外,如微信和QQ?) 。