注意: WorkManager 需要 compileSdk 版本 28 或更高版本
buildscript -->
respositories --> 加入: maven { url "https://jitpack.io" }
allprojects -->
respositories --> 加入: maven { url "https://jitpack.io" }
--java
implementation "android.arch.work:work-runtime:1.0.1"
--java ---> AndroidX:
implementation "androidx.work:work-runtime:2.2.0"
//workManager支持RxJava2
implementation "androidx.work:work-rxjava2:2.3.4"
--kotlin:
implementation "androidx.work:work-runtime-ktx:2.3.4"
添加约束:例如指定工作应仅在设备空闲且接通电源时运行,
参考链接:https://developer.android.com/reference/androidx/work/Constraints.Builder
初始延迟:制定工作在经过最短的出式延迟后启动
重试:如果需要让workManager重新城市执行您的任务,可以从工作器返回Result.retry()
退避政策:定义了在后续重试的尝试过程中,退避延迟时间以怎样的方式增长,默认按照EXPONENTIAL延长
定义任务的输入/输出:当任务需要数据以输入参数的形式传入,或者将数据返回为结果,输入值和输出值以键值对的形式存储在Data对象中
标记工作:通过为任意WorkRequest对象分配标记字符串,按逻辑对任务进行人族,这样就可以对使用特定标记的所有任务执行操作
BLOCKED : 表示当前有尚未完成的前提性工作
ENQUEUED : 表示 工作能够在满足约束和时机条件后可立即执行
RUNNING : 表示工作器在活跃的执行
SUCCEEDED : 工作期返回成功的状态,此时是一种终止的状态,且只有OneTimeWorkRequest可以进入这种状态
FAILED : 工作期返回失败的状态,此时是一种终止的状态,所有依赖的工作也会被标记为FAILED状态,且只有OneTimeWorkRequest可以进入这种状态
CANCELLED : 当明确取消尚未终止的WorkRequest时,它会进入CANCELLED状态,所有依赖工作也会被标记为CANCELLED状态,且不会运行
5. 观察/监听工作的状态
思路:将工作加入队列后,您可以根据WorkManager检查其状态,状态信息在WorkInfo对象中提供,包括工作的id、标签、当前状态和任何输出数据
方式一:对于特定的WorkRequest,可以利用:
WorkManager.getWorkInfoById(UUID)
或
WorkManager.getWorkInfoByIdLiveData(UUID) 来通过 WorkRequest id 检索其 WorkInfo.
方式二:
对于指定的标记,可以利用:
WorkManager.getWorkInfosByTag(String)
或
WorkManager.getWorkInfosByTagLiveData(String) 检索所有匹配的 WorkRequest 的 WorkInfo 对象
方式三:
对于唯一工作名称,可以利用:
WorkManager.getWorkInfosForUniqueWork(String)
或
WorkManager.getWorkInfosForUniqueWorkLiveData(String) 检索所有匹配的 WorkRequest 的WorkInfo 对象。
示例代码:
WorkManager.getInstance(myContext).getWorkInfoByIdLiveData(uploadWorkRequest.getId()).observe(lifecycleOwner, new Observer() {
@Override
public void onChanged(@Nullable WorkInfo workInfo) {
if (workInfo != null && workInfo.state == WorkInfo.State.SUCCEEDED) {
displayMessage("Work finished!")
}
}
});
通过获取WorkInfo对象的实例,此对象后一个返回的Data的新getProgress()方法获取进度
在工作任务初始化的时候,通过setProgressAsync(new Data.Builder().putInt(PROGRESS, 0).build()); 将讲进度置为0
在工作任完成的时候,通过setProgressAsync(new Data.Builder().putInt(PROGRESS,100).build()); 将讲进度置为100
观察进度,代码示例:
WorkManager.getInstance(getApplicationContext())
// requestId is the WorkRequest id
.getWorkInfoByIdLiveData(requestId)
.observe(lifecycleOwner, new Observer() {
@Override
public void onChanged(@Nullable WorkInfo workInfo) {
if (workInfo != null) {
Data progress = workInfo.getProgress();
int value = progress.getInt(PROGRESS, 0)
// Do something with progress
}
}
});
可以使用WorkManager创建工作链并为其排队,工作链用于指定多个关联任务并定义这些任务的运行顺序.
思路:
使用 WorkManager.beginWith(OneTimeWorkRequest) 或 WorkManager.beginWith(List),这会返回 WorkContinuation 实例;
通过 WorkContinuation 使用 WorkContinuation.then(OneTimeWorkRequest) 或 WorkContinuation.then(List) 来添加从属 OneTimeWorkRequest。
每次调用 WorkContinuation.then(...) 都会返回一个新的 WorkContinuation 实例。如果添加了 OneTimeWorkRequest 的 List,这些请求可能会并行运行。
最后,您可以使用 WorkContinuation.enqueue() 方法为 WorkContinuation 链排队
示例代码:
OneTimeWorkRequest compress =
new OneTimeWorkRequest.Builder(CompressWorker.class)
.setInputMerger(ArrayCreatingInputMerger.class)
.setConstraints(constraints)
.build();
WorkManager.getInstance(myContext)
// Candidates to run in parallel
.beginWith(Arrays.asList(filter1, filter2, filter3))
.then(compress)
.then(upload)
// Don't forget to enqueue()
.enqueue();
代码解析:
OverwritingInputMerger: 会尝试将所有输入中的所有键添加到输出中。如果发生冲突,它会覆盖先前设置的键。
ArrayCreatingInputMerger: 会尝试合并输入,并在必要时创建数组.
父级别任务的输出将作为输入传递给子级
父级别的请求任务都成功完成时,即返回Result.success时,才会被解除阻塞变为ENQUEUED状态.
父级别请求任务返回失败,则丛书的请求也都会被标记为FAILED状态
父级别请求任务被取消,则丛书的请求也都会被标记为CANCELLED状态
如果不需要运行前加入队列,则可以申请取消
思路:使用其od并调用WorkManager.cancelWorkById(UUID) 来取消单个 WorkRequest:
示例代码:
WorkManager.cancelWorkById(workRequest.getId());
当应用有时可能需要定期运行某些任务,例如:定期备份、下载应用中的新鲜内容,或者上传日志到服务器,此时需要将 PeriodicWorkRequest 用于这种需要定期执行的任务
定期工作请求的示例代码:
Constraints constraints = new Constraints.Builder()
.setRequiresCharging(true)
.build();
PeriodicWorkRequest saveRequest =
new PeriodicWorkRequest.Builder(SaveImageFileWorker.class, 1, TimeUnit.HOURS)
.setConstraints(constraints)
.build();
WorkManager.getInstance(myContext)
.enqueue(saveRequest);
当需要创建一个唯一工作链,可以使用:
WorkManager.beginUniqueWork(String, ExistingWorkPolicy, OneTimeWorkRequest) 代替 beginWith();