作者:tuacy
链接:https://www.jianshu.com/p/d00243f411e2
WorkManager架构组件是用来管理后台工作任务。这个时候你可能会奇怪了Android不是已经 有很多管理后台任务的类了么,比如JobScheduler, AlarmManger、在比如AsyncTask, ThreadPool。WorkManager。WorkManager的优势在哪里,我们为啥要使用WorkManager。我们从两个方面来说明WorkManager的优势
WorkManager对比JobScheduler, AlarmManger的优势:我们要知道虽然AlarmManager是一直存在但是JobScheduler是Android 5.x之后才有的。WorkManager的底层实现,会根据你的设备API的情况,自动选用JobScheduler, 或是AlarmManager来实现后台任务。
WorkManager对比AsyncTask, ThreadPool的优势:WorkManager里面的任务在应用退出之后还可以继续执行。AsyncTask, ThreadPool里面的任务在应用退出之后不会执行。
WorkManager适用于那些在应用退出之后任务还需要继续执行的需求(比如应用数据上报服务器的情况),对应那些在应用退出的之后任务也需要终止的情况就需要选择ThreadPool、AsyncTask来实现。
一、WorkManager相关类介绍
想使用WorkManager组件库,第一步咱们得先了解下WorkManager里面相关的几个类。
1.1、Worker
Worker用于指定需要执行的具体任务。任务的具体逻辑在Worker里面写。
Worker是个抽象类。所以我们需要继承并实现这个类在定义自己的任务。
Worker类里面几个比较关键的函数:任务逻辑实现函数,任务输入数据的获取函数,任务输出数据的设置函数。
1 /** 2 * 任务逻辑 3 * @return 任务的执行情况,成功,失败,还是需要重新执行 4 */
5 @WorkerThread
6 public abstract @NonNull Worker.Result doWork();
7
8 /** 9 * 任务的输入数据,有的时候可能需要我们传递参数进去,比如下载文件我们需要传递文件路基进去,10 * 在doWork()函数中通过getInputData()获取到我们传递进来的参数11 * @return Data参数12 */
13 public final @NonNull Data getInputData() {
14 return mExtras.getInputData();
15 }
16
17 /**18 * 设置我们任务输出结果19 * @param outputData 结果20 */
21 public final void setOutputData(@NonNull Data outputData) {
22 mOutputData = outputData;
23 }
1 doWork()函数的返回值:
Worker.Result.SUCCESS:任务执行成功。
Worker.Result.FAILURE:任务执行失败。
Worker.Result.RETRY:任务需要重新执行,需要配合WorkRequest.Builder里面的setBackoffCriteria()函数使用。
1.2、WorkRequest
WorkRequest代表一个单独的任务,是对Worker任务的包装,一个WorkRequest对应一个Worker类。我们可以通过WorkRequest来给Worker类添加约束细节,比如指定任务应该运行的环境,任务的输入参数,任务只有在有网的情况下执行等等。WorkRequest是一个抽象类,组件里面也给两个相应的子类:OneTimeWorkRequest(任务只执行一遍)、PeriodicWorkRequest(任务周期性的执行)。
WorkRequest.Builder: 创建WorkRequest对象的帮助类。
Constraints:指定任务运行的限制条件(例如,"仅当连接到网络时")。使用Constraint.Builder来创建Constraints,并在创建WorkRequest之前把Constraints传给WorkRequest.Builder的setConstraints()函数。
WorkRequest里面常用函数介绍
1 /** 2 * 获取 WorkRequest对应的UUID 3 */
4 public @NonNull UUID getId();
5
6 /** 7 * 获取 WorkRequest对应的UUID string 8 */
9 public @NonNull String getStringId();
10
11 /**12 * 获取WorkRequest对应的WorkSpec(包含了任务的一些详细信息)13 */
14 public @NonNull WorkSpec getWorkSpec();
15
16 /**17 * 获取 WorkRequest对应的tag18 */
19 public @NonNull Set getTags();
20
21 public abstract static class Builder<B extends WorkRequest.Builder, W extends WorkRequest> {
22 ...
23
24 /**25 * 设置任务的退避/重试策略。比如我们在Worker类的doWork()函数返回Result.RETRY,让该任务又重新入队。26 */
27 public @NonNull B setBackoffCriteria(28 @NonNull BackoffPolicy backoffPolicy,29 long backoffDelay,30 @NonNull TimeUnit timeUnit);
31
32 /**33 * 设置任务的运行的限制条件,比如有网的时候执行任务,不是低电量的时候执行任务34 */
35 public @NonNull B setConstraints(@NonNull Constraints constraints);
36
37 /**38 * 设置任务的输入参数39 */
40 public @NonNull B setInputData(@NonNull Data inputData);
41
42 /**43 * 设置任务的tag44 */
45 public @NonNull B addTag(@NonNull String tag);
46
47 /**48 * 设置任务结果保存时间49 */
50 public @NonNull B keepResultsForAtLeast(long duration, @NonNull TimeUnit timeUnit);
51 @RequiresApi(26)
52 public @NonNull B keepResultsForAtLeast(@NonNull Duration duration);
53 ...
54 }
这里要稍微提下Builder的setBackoffCriteria()函数的使用场景,比较常用,一般当我们任务执行失败的时候任务需要重试的时候会用到这个函数,在任务执行失败的时候Worker类的doWork()函数返回Result.RETRY告诉这个任务要重试。那重试的策略就是通过setBackoffCriteria()函数来设置的。BackoffPolicy有两个值LINEAR(每次重试的时间线性增加,比如第一次10分钟,第二次就是20分钟)、EXPONENTIAL(每次重试时间指数增加)。
1.3、WorkManager
管理任务请求和任务队列,我们需要把WorkRequest对象传给WorkManager以便将任务编入队列。通过WorkManager来调度任务,以分散系统资源的负载。
WorkManager常用函数介绍
1 /** 2 * 任务入队 3 */
4 public final void enqueue(@NonNull WorkRequest... workRequests);
5 public abstract void enqueue(@NonNull List extends WorkRequest> workRequests);
6
7 /** 8 * 链式结构的时候使用,从哪些任务开始。 9 * 比如我们有A,B,C三个任务,我们需要顺序执行。那我们就可以WorkManager.getInstance().beginWith(A).then(B).then(C).enqueue();10 */
11 public final @NonNull WorkContinuation beginWith(@NonNull OneTimeWorkRequest...work);
12 public abstract @NonNull WorkContinuation beginWith(@NonNull List work);1314 /**15 * 创建一个唯一的工作队列,唯一工作队列里面的任务不能重复添加16 */17 public final @NonNull WorkContinuation beginUniqueWork(18 @NonNull String uniqueWorkName,19 @NonNull ExistingWorkPolicy existingWorkPolicy,