9.WorkManager

WorkManager概述

1
2
3
WorkManager 是适合用于持久性工作的推荐解决方案。如果工作始终要通过应用重启和系统重新启动来调度,便是持久性的工作。由于大多
数后台处理操作都是通过持久性工作完成的,因此 WorkManager 是适用于后台处理操作的主要推荐 API。
不依赖于当前用户进程:当前用户进行killed,任务能够继续执行;
1
2
3
4
5
WorkManager 适用于需要可靠运行的工作,即使用户导航离开屏幕、退出应用或重启设备也不影响工作的执行。例如:

向后端服务发送日志或分析数据。
定期将应用数据与服务器同步。
WorkManager 不适用于那些可在应用进程结束时安全终止的进程内后台工作。它也并非对所有需要立即执行的工作都适用的通用解决方案。

3个主要的核心类

image-20231116151435427

基础使用

1
implementation "androidx.work:work-runtime:$work_version"

work类定义 (extends Worker)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class DemoWork extends Worker {
public static final String TAG = DemoWork.class.getSimpleName();
private Context context;
private WorkerParameters workerParams;

public DemoWork(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
this.context = context;
this.workerParams = workerParams;
}
@NonNull
@Override
public Result doWork() {
Log.e(TAG, "doWork----------**-----------: 后台任务执行了");
// 接收Activity传递过来的数据
final String dataString = workerParams.getInputData().getString("data");
Log.e(TAG, "doWork: 接收Activity传递过来的数据:" + dataString);
// 反馈数据 给 Activity
// 把任务中的数据回传到activity中
// Data outputData = new Data.Builder().putString("data", "执行完任务将结果和数据回传给Activity").build();
@SuppressLint("RestrictedApi")
Result.Success success = new Result.Success();
// return new Result.Failure(); // 本地执行 doWork 任务时 失败
// return new Result.Retry(); // 本地执行 doWork 任务时 重试
// return new Result.Success(); // 本地执行 doWork 任务时 成功 执行任务完毕
return success;
}
}

单次执行及延迟调用的示例

1
2
3
4
5
6
7
  //工作通过把WorkRequest传入WorkManager中进行定义。使WorkManager可以调度任何工作;
OneTimeWorkRequest oneTimeWorkRequest =
new OneTimeWorkRequest.Builder(DemoWork.class)
.setInitialDelay(10,TimeUnit.SECONDS)
.build();

WorkManager.getInstance(this).enqueue(oneTimeWorkRequest);

WorkRequest 对象包含 WorkManager 调度和运行工作所需的所有信息

WorkRequest 本身是抽象基类。该类有两个派生实现,可用于创建 OneTimeWorkRequest和 PeriodicWorkRequest 请求。顾名思义,OneTimeWorkRequest 适用于调度非重复性工作,而PeriodicWorkRequest则更适合调度以一定间隔重复执行的工作。

调度一次性工作

1
2
3
4
5
6
WorkRequest myWorkRequest = OneTimeWorkRequest.from(MyWork.class);
//对于更复杂的工作,可以使用构建器:
WorkRequest myWorkRequest =
new OneTimeWorkRequest.Builder(MyWork.class)
//添加自定义规则
.build();

调度定期工作

1
2
3
4
5
6
7
8
有时可能需要定期运行某些工作。例如,您可能要定期备份数据、定期下载应用中的新鲜内容或者定期上传日志到服务器。

使用 PeriodicWorkRequest 创建定期执行的 WorkRequest 对象的方法如下:
PeriodicWorkRequest saveRequest =
new PeriodicWorkRequest.Builder(SaveImageToFileWorker.class, 1, TimeUnit.HOURS)
// Constraints
.build();
//在此示例中,工作的运行时间间隔定为一小时

1
2
3
4
//执行加急工作 (从 WorkManager 2.7 开始支持)
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
//延迟工作*
.setInitialDelay(10, TimeUnit.MINUTES)

工作约束

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
为了让工作在指定的环境下运行,我们可以给WorkRequest添加约束条件,常见的约束条件如下所示。 - **NetworkType**:约束运行工作
所需的网络类型,例如 Wi-Fi (UNMETERED)。 - **BatteryNotLow** :如果设置为 true,那么当设备处于“电量不足模式”时,工作不
会运行。 - **RequiresCharging**:如果设置为 true,那么工作只能在设备充电时运行。 - **DeviceIdle**:如果设置为 true,则
要求用户的设备必须处于空闲状态才能运行工作。 - **StorageNotLow**:如果设置为 true,那么当用户设备上的存储空间不足时,工作
不会运行。

例如,以下代码会构建了一个工作请求,该工作请求仅在用户设备正在充电且连接到 Wi-Fi 网络时才会运行。
Constraints constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.UNMETERED)
.setRequiresCharging(true)
.build();

WorkRequest myWorkRequest =
new OneTimeWorkRequest.Builder(MyWork.class)
.setConstraints(constraints)
.build();