WorkManager 简介 1
其基础是:
- Api 23+ (6.0 及以上)2: 基于
JobScheduler
3 - API 14-22(6.0 以下): 自定制用于 的
AlarmManager
4 +BroadcastReceiver
- 了解一下 WorkManager 的前世今生5
- 但我们使用的时候并不需要关注使用的 api,交给 WorkManager 即可,由 WorkManager 让它选择最佳选项
18 年 IO 大会发布的Android Jetpack
组件其中之一,WorkManager
、Paging
、Navigation
、Slices
,兼容 kotlin 语言。其中 WorkManager 一句话概括是:在条件满足(网络状态、电池条件)满足时,管理运行后台 work(即使你的应用没启动也能保证任务能被执行)。
WorkManager 尽可能使用框架 JobScheduler,来帮助优化电池寿命和批处理作业; api 23 以下设备,如果应用使用了 Firebase JobDispatcher 和其它的 Firebase 依赖时,尝试使用 Firebase JobDispatcher
,否则,就使用自定义的AlarmManager + BroadcastReceiver 实现。
几个关键的类
一、Worker 指定我们需要执行的任务,继承于 ListenableWorker
- 数据库使用的是 Room 数据库,用于保存数据
doWork()
是运行于后台线程的同步方法- 返回值是
Result
- 成功返回:
Result.success()
- 失败:
Result.failure()
- 需要稍后重试:
Result.retry()
- 返回值是
- 抽象方法,
doWork()
需要我们实现我们要做的 work - 注意
doWork()
中不能更新 UI(需要在主线程中做的事情,Toast 也不行)Can't toast on a thread that has not called Looper.prepare()
- 一般我们使用
Worker
,也是官方推荐的
ListenableWorker
|
+--------------------------+-------------------------+--------------------+
| | | |
CombineContinuationsWorker ConstraintTrackingWorker CoroutineWorker Worker
ListenableWorker
所有的 Work 在
ListenableWorker
中完成,ListenableWorker
在WorkManager
中是异步执行的
ListenableWorker
在运行时由WorkerFactory
实例化,配置是Configuration
,在主线程中调用其方法startWork()
如果一个 work 被制止后,后来又因为某种原因重新启动后,会重新实例化一个
ListenableWorker
,startWork()
在每个ListenableWorker
中只会被调用一次
一个
ListenableWorker
最大执行时长为 10 min,并会返回ListenableWorker.Result
,如果时间到了, work 将会被停止,ListenableFuture
也会被取消
ListenableWorker.Result
有三个子类:Result.Success
表示任务执行成功Result.FAILURE
表示任务执行失败Result.Retry
之后再尝试执行该任务
二、WorkManager 抽象类,实现 WorkManagerImpl 将 WorkRequest 入队和管理 WorkRequest
- 进行入队(
enqueue()
)等操作、beginWith()
等、查询 WorkRequest 信息[getWorkInfoByIdLiveData``getWorkInfoById
] 等 WorkManager
支持两种 work:OneTimeWorkRequest
和PeriodicWorkRequest
WorkManagerImpl
实例化WorkManager
,为单例模式,初始化在initialize()
方法里,调用在WorkManagerInitializer
的 onCreate 中,WorkManagerInitializer
继承于ContentProvider
,所以在系统启动的时候就会实例化WorkManager
//sDelegatedInstance 和 sDefaultInstance 都是 WorkManager 的实例,所以不能共存
synchronized (sLock) {
if (sDelegatedInstance != null && sDefaultInstance != null) {
throw new IllegalStateException("WorkManager is already initialized. Did you "
+ "try to initialize it manually without disabling "
+ "WorkManagerInitializer? See "
+ "WorkManager#initialize(Context, Configuration) or the class level"
+ "Javadoc for more information.");
}
if (sDelegatedInstance == null) {
context = context.getApplicationContext(