一、WorkManager是什么?
WorkManager 是一个 API,使您可以轻松调度那些即使在退出应用或重启设备时仍应运行的可延期异步任务。WorkManager API 是一个针对先前的 Android 后台调度 API(包括 FirebaseJobDispatcher、GcmNetworkManager 和 JobScheduler)的合适的建议替换组件。WorkManager 在新版一致性 API 中整合了其前身的功能,该 API 支持 API 级别 14,同时可保证电池续航时间。.
在后台,WorkManager 根据以下条件使用底层作业调度服务:
.
.
二、作用
除了具备更为简单且一致的 API 之外,WorkManager 还具备许多其他关键优势,其中包括:
1. 工作约束
使用工作约束明确定义工作运行的最佳条件。(例如,仅在设备采用 Wi-Fi 网络连接时、当设备处于空闲状态或者有足够的存储空间时运行。)
2. 强大的调度
WorkManager允许您使用灵活的调度窗口调度工作,以运行一次性或重复工作。还可以对工作进行标记或命名,以便调度唯一的、可替换的工作以及监控或取消工作组。已调度的工作存储在内部托管的 SQLite 数据库中,由 WorkManager 负责确保该工作持续进行,并在设备重新启动后重新调度。此外,WorkManager 遵循低电耗模式等省电功能和最佳做法,因此您在这方面无需担心。
3. 灵活的重试政策
有时工作会失败。WorkManager 提供了灵活的重试政策,包括可配置的指数退避政策。
4. 工作链接
对于复杂的相关工作,请使用流畅自然的界面将各个工作任务链接在一起,这样您便可以控制哪些部分依序运行,哪些部分并行运行。对于每项工作任务,您可以定义工作的输入和输出数据。将工作链接在一起时,WorkManager 会自动将输出数据从一个工作任务传递给下一个工作任务。
优点
-
WorkManager对比JobScheduler, AlarmManger的优势:我们要知道虽然AlarmManager是一直存在但是JobScheduler是Android 5.x之后才有的。WorkManager的底层实现,会根据你的设备API的情况,自动选用JobScheduler, 或是AlarmManager来实现后台任务。
-
WorkManager对比AsyncTask, ThreadPool的优势:WorkManager里面的任务在应用退出之后还可以继续执行。AsyncTask, ThreadPool里面的任务在应用退出之后不会执行。
WorkManager适用于那些在应用退出之后任务还需要继续执行的需求(比如应用数据上报服务器的情况),对应那些在应用退出的之后任务也需要终止的情况就需要选择ThreadPool、AsyncTask来实现。
.
.
三、使用步骤
1.引入库
将以下依赖项添加到应用的 build.gradle 文件中:
dependencies {
def work_version = "2.4.0"
implementation "androidx.work:work-runtime:$work_version"
androidTestImplementation "androidx.work:work-testing:$work_version"
}
注意:
您始终可以在 WorkManager 版本页面上找到最新版本的 WorkManager,包括 Beta 版、Alpha 版和候选版本。
2.定义Worker 类
工作使用 Worker 类定义。doWork() 方法在 WorkManager 提供的后台线程上同步运行
代码如下(示例):
public class MyWorker extends Worker {
public MyWorker (@NonNull Context context,@NonNull WorkerParameters params) {
super(context, params);
}
@Override
/**
* 任务逻辑
* @return 任务的执行情况,成功,失败,还是需要重新执行
*/
public Result doWork() {
//需要后台执行的任务的逻辑写在下面
...
// 返回任务执行的结果
return Result.success();
}
}
从 doWork() 返回的 Result 会通知 WorkManager 服务工作是否成功,以及工作失败时是否应重试工作。
- Result.success():工作成功完成。
- Result.failure():工作失败。
- Result.retry():工作失败,应根据其重试政策在其他时间尝试。
2.创建 WorkRequest
定义工作后,必须使用 WorkManager 服务进行调度该工作才能运行。对于如何调度工作,WorkManager 提供了很大的灵活性。您可以将其安排为在某段时间内定期运行,也可以将其安排为仅运行一次。
WorkRequest是一个抽象类,组件里面也给两个相应的子类:OneTimeWorkRequest(任务只执行一遍)、PeriodicWorkRequest(任务周期性的执行)
不论您选择以何种方式调度工作,请始终使用 WorkRequest。Worker 定义工作单元,WorkRequest(及其子类)则定义工作运行方式和时间。在最简单的情况下,您可以使用 OneTimeWorkRequest
代码如下(示例):
WorkRequest MyWorkRequest =
new OneTimeWorkRequest.Builder(MyWorker.class)
.build();
3.将 WorkRequest 提交给系统
最后,您需要使用 enqueue() 方法将 WorkRequest 提交到 WorkManager
WorkManager
.getInstance(myContext)//传递参数给Worker 类
.enqueue(MyWorkRequest);//提交给系统
执行工作器的确切时间取决于 WorkRequest 中使用的约束和系统优化方式。WorkManager 经过设计,能够在满足这些约束的情况下提供最佳行为。
总结
到这里WorkManager的简单使用就介绍完了,下面再介绍WorkManager相关类的作用和注意点。
.
.
四、 WorkManager相关类介绍
1. Worker类
Worker类用于指定需要执行的具体任务。任务的具体逻辑在Worker里面写,Worker是个抽象类。所以我们需要继承并实现这个类在定义自己的任务。
Worker类里面几个比较关键的函数:任务逻辑实现函数,任务输入数据的获取函数,任务输出数据的设置函数。
Worker类的源码:
/**
* 任务逻辑
* @return 任务的执行情况,成功,失败,还是需要重新执行
*/
@WorkerThread
public abstract @NonNull Worker.Result doWork();
/**
* 任务的输入数据,有的时候可能需要我们传递参数进去,比如下载文件我们需要传递文件路基进去,
* 在doWork()函数中通过getInputData()获取到我们传递进来的参数
* @return Data参数
*/
public final @NonNull Data getInputData() {
return mExtras.getInputData();
}
/**
* 设置我们任务输出结果
* @param outputData 结果
*/
public final void setOutputData(@NonNull Data outputData) {
mOutputData = outputData;
}
其中doWork()函数的返回值:
- Worker.Result.SUCCESS:任务执行成功。
- Worker.Result.FAILURE:任务执行失败。
- Worker.Result.RETRY:任务需要重新执行,如果出现这个返回结果,就需要与WorkRequest.Builder中的setBackoffCriteria()函数一起使用。
定义 Worker类
前台和后台服务,有时候需要传入数据,在Activity定义Data,将需要传入的数据包装一下,然后通过WorkRequest的setInputData()传入
Data data = new Data.Builder().putString("params", "hello").build();
PeriodicWorkRequest request = new PeriodicWorkRequest.Builder(MyWorker.class, 15, TimeUnit.SECONDS)
.setInputData(data)
.build();
这个传入的值,可以在Worker中获取
public class MyWorker extends Worker {
public MyWorker (@NonNull Context context,@NonNull WorkerParameters params) {
super(