Android架构组件-WorkManager,来自阿里巴巴佛系Android程序员的指南

本文详细介绍了WorkManagerAPI在Android中如何管理和调度任务,包括Worker、WorkRequest、Constraints的使用,以及如何创建重复、周期性、有序的任务执行流程。
摘要由CSDN通过智能技术生成

// optional - Firebase JobDispatcher support
implementation “android.arch.work:work-firebase:$work_version”

// optional - Test helpers
androidTestImplementation “android.arch.work:work-testing:$work_version”
}

类和概念


WorkManager API使用了几个不同的类,在某些情况下,我们需要继承其中一个API类。

下面我们来看看最重要的几个类:

  • Worker:指定我们需要执行的任务。 WorkManager API包含一个抽象的Worker类,我们需要继承这个类并且在这里执行工作。

  • WorkRequest:代表一个单独的任务。一个WorkRequest 对象指定哪个 Woker 类应该执行该任务,而且,我们还可以向 WorkRequest 对象添加详细信息,指定任务运行的环境等。每个 WorkRequest 都有一个自动生成的唯一ID,我们可以使用该ID来执行诸如取消排队的任务或获取任务状态等内容。 WorkRequest 是一个抽象类,在代码中,我们需要使用它的直接子类,OneTimeWorkRequestPeriodicWorkRequest.。

  • WorkRequest.Builder:用于创建WorkRequest对象的辅助类,同样,我们要使用它的一个子类,OneTimeWorkRequest.BuilderPeriodicWorkRequest.Builder

  • Constraints:指定任务在何时运行(例如,“仅在连接到网络时”)。我们可以通过Constraints.Builder 来创建Constraints对象,并在创建WorkRequest之前,将 Constraints 对象传递给 WorkRequest.Builder

  • WorkManager:将WorkRequest入队和管理WorkRequest。我们要将WorkRequest对象传递给 WorkManagerWorkManager 以这样的方式调度任务,以便分散系统资源的负载,同时遵守我们指定的约束条件。

  • WorkStatus:包含有关特定任务的信息。WorkManager 为每个 WorkRequest 对象提供一个 LiveDataLiveData持有一个WorkStatus对象,通过观察LiveData,我们可以确定任务的当前状态,并在任务完成后获取返回的任何值。

典型的工作流程


假设我们正在开发一个照片库应用,并且该应用程序需要定期压缩其存储的图像,我们想使用 WorkManager API 调度图像压缩任务,在这种情况下,我们并不需要关心压缩发生在何时,我们只需要设置这个任务然后就可以忘记它。

首先,我们需要定义自己的Worker类,然后重写此类的 doWork() 方法,我们需要指定Worker类如何执行这个操作,但是不应该出现任何关于任务在何时运行的信息。

public class CompressWorker extends Worker {
@Override
public Worker.WorkerResult doWork() {

// Do the work here–in this case, compress the stored images.
// In this example no parameters are passed; the task is
// assumed to be “compress the whole library.”
myCompress();

// Indicate success or failure with your return value:
return WorkerResult.SUCCESS;

// (Returning RETRY tells WorkManager to try this task again
// later; FAILURE says not to try again.)
}
}

接下来,我们要创建一个基于此WorkerOneTimeWorkRequest对象,然后使用WorkManager让这个任务入队:

OneTimeWorkRequest compressionWork = new OneTimeWorkRequest.Builder(CompressWorker.class).build();
WorkManager.getInstance().enqueue(compressionWork);

WorkManager会选择适当的时间运行这个任务,平衡诸如系统负载,设备是否插入等考虑因素。在多数情况下,如果我们没有指定任何约束条件,WorkManager会立即运行我们的任务。如果我们需要检查任务的状态,我们可以通过获取合适的LiveData <WorkStatus>的句柄来获取WorkStatus对象。例如,如果我们想检查任务是否完成,可以使用如下代码:

WorkManager.getInstance().getStatusById(compressionWork.getId())
.observe(lifecycleOwner, workStatus -> {
// Do something with the status
if (workStatus != null && workStatus.getState().isFinished())
{ … }
});

任务约束条件

如果我们愿意,我们还可以限制任务运行的时间。例如,我们可能想要指定该任务只在设备闲置并接通电源时运行。在这种情况下,我们需要创建一个OneTimeWorkRequest.Builder对象,并使用这个构造器创建实际的OneTimeWorkRequest

// Create a Constraints that defines when the task should run
Constraints myConstraints = new Constraints.Builder()
.setRequiresDeviceIdle(true)
.setRequiresCharging(true)
// Many other constraints are available, see the
// Constraints.Builder reference
.build();

// …then create a OneTimeWorkRequest that uses those constraints
OneTimeWorkRequest compressionWork = new OneTimeWorkRequest.Builder(CompressWorker.class)
.setConstraints(myConstraints)
.build();

然后像之前代码一样将新的OneTimeWorkRequest对象传递给WorkManager.enqueue()WorkManager在查找运行任务的时间时会考虑我们的约束条件。

取消任务

当我们将任务入列后,我们还可以取消这个任务。要取消任务,我们需要这个任务的Work ID,当然Work ID可以从WorkRequest对象中获取。例如,以下代码将取消上一节中的compressionWork请求:

UUID compressionWorkId = compressionWork.getId();
WorkManager.getInstance().cancelByWorkId(compressionWorkId);

WorkManager 会尽最大努力取消任务,但实质上这是不确定的 - 当我们尝试取消任务时,任务可能已经运行或完成。WorkManager还提供方法来取消 **唯一工作序列(这个概念在下面会讲到)**中的所有任务,或尽最大努力的取消具有指定标记的所有任务。

高级功能


WorkManager API 的核心功能可以使开发者能够创建简单的、即开即忘的任务,除此之外,API 还提供了高级功能,可以让我们设置更多精准的请求。

重复执行的任务

我们可能需要重复执行一项任务,例如,照片管理应用不会只想压缩其照片一次。更有可能的是,它会希望每隔一段时间检查一次照片,并查看是否有任何新的或改变的图像需要压缩,这个循环任务可以压缩它找到的图像,或者它可以启动新的“压缩图像”任务。

要创建循环任务,要使用PeriodicWorkRequest.Builder类创建一个PeriodicWorkRequest对象,然后将PeriodicWorkRequest以与OneTimeWorkRequest对象相同的方式入列。例如,假如我们定义了一个PhotoCheckWorker类来识别需要压缩的图像,如果我们想每12小时运行一次这个任务,我们可以像下面这样创建一个PeriodicWorkRequest对象 :

new PeriodicWorkRequest.Builder photoWorkBuilder =
new PeriodicWorkRequest.Builder(PhotoCheckWorker.class, 12,
TimeUnit.HOURS);
// …if you want, you can apply constraints to the builder here…

// Create the actual work object:
PeriodicWorkRequest photoWork = photoWorkBuilder.build();
// Then enqueue the recurring task:
WorkManager.getInstance().enqueue(invWork);

WorkManager 尝试按照我们请求的时间间隔运行任务,但要受到我们施加的限制和其他要求的限制。

链式任务

有时候我们想让应用程序按照特定的顺序运行多个任务。 WorkManager允许我们创建和排队多个任务的工作序列,以及它们应该以什么顺序运行。

例如,假如我们的应用有三个 OneTimeWorkRequest 对象:workA, workB, 和 workC,这些任务必须按照该顺序执行。要想将它们排队,请使用WorkManager.beginWith() 方法创建一个序列,并传递第一个OneTimeWorkRequest对象,该方法返回一个WorkContinuation对象,该对象定义了一系列任务。然后依次使用 WorkContinuation.then()添加剩余的OneTimeWorkRequest对象,最后使用 WorkContinuation.enqueue()排序整个序列:

WorkManager.getInstance()
.beginWith(workA)
// Note: WorkManager.beginWith() returns a
// WorkContinuation object; the following calls are
// to WorkContinuation methods
.then(workB) // FYI, then() returns a new WorkContinuation instance
.then(workC)
.enqueue();

WorkManager根据每个任务的指定约束以请求的顺序运行任务,如果任何任务返回Worker.WorkerResult.FAILURE,则整个序列结束。

我们还可以将多个OneTimeWorkRequest对象传递给beginWith().then() 调用中的任何一个。如果我们将多个OneTimeWorkRequest对象传递给单个方法调用,那么WorkManager将在运行序列中其余部分任务前运行所有这些任务(并行)。例如:

WorkManager.getInstance()
// First, run all the A tasks (in parallel):
.beginWith(workA1, workA2, workA3)
// …when all A tasks are finished, run the single B task:
.then(workB)
// …then run the C tasks (in any order):
.then(workC1, workC2)
.enqueue();

我们可以通过使用WorkContinuation.combine()方法连接多个链来创建更复杂的序列。例如,假设我们想要像下图运行一个序列:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

小结

有了这么多优秀的开发工具,可以做出更高质量的Android应用。

当然了,“打铁还需自身硬”,想要写出优秀的代码,最重要的一点还是自身的技术水平,不然用再好的工具也不能发挥出它的全部实力。

在这里我也分享一份大佬自己收录整理的Android学习PDF+架构视频+面试文档+源码笔记,还有高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料这些都是我闲暇还会反复翻阅的精品资料。在脑图中,每个知识点专题都配有相对应的实战项目,可以有效的帮助大家掌握知识点。

总之也是在这里帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习

收录整理的Android学习PDF+架构视频+面试文档+源码笔记,还有高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料这些都是我闲暇还会反复翻阅的精品资料。在脑图中,每个知识点专题都配有相对应的实战项目,可以有效的帮助大家掌握知识点。

总之也是在这里帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习

如果你有需要的话,可以点击这里领取

  • 18
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值