WorkerManager 的基本使用
文章目录
- 一、相关类
- 二、使用
- 三、执行简单说明
- 四、定时调度任务
- 五、指定条件下执行任务
- 六、延时调度任务
- 七、Result.retry() 重试和退避
- 八、标记任务和数据的传入
一、相关类
- Worker:自定义或继承实现该类,doWork() 方法中为执行的任务;
- WorkerRequest:保存相关 Worker 的请求。
- WorkManager:进行任务执行。
二、使用
- 添加依赖
- 自定义 Worker 任务
public class MyWorker extends Worker {
private final String TAG = "MyWorker";
Map value;
public MyWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
Data inputData = workerParams.getInputData();
this.value = inputData.getKeyValueMap();
}
@NonNull
@Override
public Result doWork() {
String a = (String) value.get("value");
Log.d(TAG,"a的值为:" + a);
if("success".equals(a)) {
Log.d(TAG,"成功, a value:" + a);
return Result.success();
} else if("failure".equals(a)) {
Log.d(TAG,"失败, a value:" + a);
return Result.failure();
}
Log.d(TAG,"重试, a value:" + a);
return Result.retry();
}
}
- 创建 WorkRequest
HashMap<String,String> inputData = new HashMap(3);
inputData.put("value","success");
//数据传递,最好使用 Data.Builder() 构建,这是图省事
@SuppressLint("RestrictedApi")
Data data = new Data(inputData);
//创建携带数据的请求
WorkRequest request = new OneTimeWorkRequest.Builder(MyWorker.class)
.setInputData(data)
.build();
- 使用 WorkManager 提交 Work
WorkManager.getInstance(this).enqueue(request);
- 执行结果 Log(OneTimeWorkRequest 请求结果,不要混淆其他方式的请求)
D/MyWorker: a的值为:success
D/MyWorker: 成功, a value:success
D/MyWorker: a的值为:failure
D/MyWorker: 失败, a value:failure
D/MyWorker: a的值为:retry
D/MyWorker: 重试, a value:retry
D/MyWorker: a的值为:success
D/MyWorker: 成功, a value:success
D/MyWorker: a的值为:failure
D/MyWorker: 失败, a value:failure
D/MyWorker: a的值为:retry
D/MyWorker: 重试, a value:retry
D/MyWorker: a的值为:retry
D/MyWorker: 重试, a value:retry
D/MyWorker: a的值为:retry
D/MyWorker: 重试, a value:retry
- 请求类型
- OneTimeWorkRequest:不会循环、重复执行任务的请求。会根据策略进行任务重试,区分好重试和循环执行的区别。
- PeriodicWorkRequest:可能重复、循环执行任务的请求。类似定时调度这些就是,也会根据重试策略去重试任务的执行。(注意发生错误时重试、循环执行两者之间有可能发生冲突)
- 自定义请求:继承抽象类 WorkRequest,根据需求定义。
三、执行简单说明
- Worker.doWork() 返回值
- Result.success:任务执行成功。
- Result.failure():任务执行失败。
- Result.retry():任务执行失败,根据重试策略进行重试。
- WorkRequest 相关:
- OneTimeWorkRequest:执行一次,加急调用 WorkRequest.setExpedited() 方法;无序配置使用 from();较为复杂用 build()
WorkRequest request = new OneTimeWorkRequest.from(MyWork.class);//无需配置
WorkRequest request = new OneTimeWorkRequest.Builder(MyWork.class).build();//较为复杂的工作
- 对任务进行加急,加急的特征:
- 重要性:加急适用于对用户很重要或由用户启动的任务。
- 速度:加急工作最适合那些立即启动并在几分钟内完成的简短任务。
- 配额:限制前台执行时间的系统级配额决定了加急任务是否可以启动。
- 电源管理:电源管理限制(如省电模式和低电耗模式)不太可能影响加急工作。
- 延迟时间:系统立即执行加急工作,前提是系统的当前工作负载允许执行此操作。这意味着这些任务对延迟事件较为敏感,不能安排到以后执行。
配额说明:系统必须为加急任务分配应用执行事件,才能执行任务。执行时间受到配额限制,当上一个加急任务未完成分配时间的执行或任务完成的话,下一个加急任务不会执行。配额只有在应用处于后台才起效,应用处于前台无限制。 - 加急要求:WorkManager 2.7 以上,所有的 ListenableWorker 都必须实现 getForegroundInfo 方法。
- 加急要求二------信息获取:在 Android12 以下的Android 上,执行任务的 WorkManager 需实现 getForegroundInfoAsync() 方法,该方法可获得加急信息。Android12 以上不用实现。
- 加急使用,构建 Request 时调用 setExpedited() 即可:
OneTImeWorkRequest request = new OneTimeWorkRequestBuilder<T>()
.setInputData(inputData)
.setExpedited(OutOfOuotaPolicy.RUN_AS_NON_EXPEDITED_WORKER_REQUEST)
.build();//加急执行
参数说明:
- OutOfOuotaPolicy.RUN_AS_NON_EXPEDITED_WORKER_REQUEST:任务作为普通任务执行。
- OutOfOuotaPolicy.DROP_WORK_REQUEST:配额不足是导致请求取消。
四、定时调度任务
简单使用 PeriodicWorkRequest 类完成定时调度
- 重复调度(说明:最短时间间隔为 15 分钟)
每隔一小时调度一次:
PeriodicWorkRequest request = new PeriodicWorkRequest.
Builder(MyWorker.class,1,TimeUnit.HOURS)
.build();//一小时间隔定时调度
参数说明
- 参数一 MyWorker.Class:自定义 Worker。
- 参数二 1:数值。
- 参数三 TimeUnit.HOURS:参数二的单位–小时。
- 灵活调度(间隔时间大于等于五分钟)
每个小时最后十五分钟调度一次:
PeriodicWorkRequest request = new PeriodicWorkRequest.
Builder(MyWorker.class,1,TimeUnit.HOURS,
15,TimeUnit.MINUTES)
.build();//每个小时的最后十五分钟进行调度
五、指定条件下执行任务
- 使用类 Constraints 完成约束,setConstraints() 包装约束
Constraints constraints = new Contraints.Builder()
.setRequiredNetworkType(NetworkType.UNMETERED)
.setRequiresCharging(true)
.build();//当网络为 Wifi,设备充电时才会进行调度
WorkRequest request = new OneTimeWorkRequest.Builder(MyWork.class)
.setConstraints(constraints)
.build();//建立请求
WorkManager manager = WorkManager.getInstance().enqueue(request);//任务调度
调度参数说明:
属性 | 说明 |
NetworkType | 约束任务执行的网络类型,如Wifi(UNMETERED) |
BatteryNotLow | 如果设置为 true,当设备处于“电量不足模式”时,任务不会i执行 |
RequiresCharging | 如果设置为 true,那只有在设备充电时,任务才会调度执行 |
Deviceldle | 如果设置为 true,则要求用户的设备处于空闲状态才能执行任务。该约束适用于执行批量任务时;若是不使用该约束,批量操作可能会导致用户设备上正在运行的其他应用的性能 |
StorageNotLow | 如果设置为 true,当用户设备上的存储空间不足时,任务不会调度执行 |
执行时期若条件未满足,该任务会停止调度,而不是继续执行。 |
六、延时调度任务
使用 setInitiaDelay() 进行延时调度。
WorkRequest request = new OneTimeWorkRequest(MyWork.class)
.setInitialDelay(10,TimeUnit.MINUTES)
.build();//加入调度队列后至少10分钟再执行
执行依旧受约束条件和系统限制。
七、Result.retry() 重试和退避
- setBackoffCriteris() 基本使用(说明:重试会与设置相差几秒,但不会低于初始退避延迟时间)
WorkRequest request =
new OneTimeWorkRequest.Builder(MyWork.class)
.setBackoffCriteria(
BackoffPolicy.LINEAR,
OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
TimeUnit.MILLISECONDS)
.build();//第一次重试10秒,每次重试时,重试间隔会依次增加 10 秒直至成功执行
说明:
- BackoffPolicy.LINEAR:退避策略。每次重试时间间隔为 上一次时间+最短退避延迟时间。若为 BackoffPolicy.EXPONENTIAL ,则此次重试时间间隔为 上次时间间隔乘以2。
- OneTimeWorkRequest.MIN_BACKOFF_MILLIS:最短退避延迟时间。初始重试时间的间隔。
- TimeUnit.MILLISECONDS:单位,此处为秒。
八、标记任务和数据的传入
- 任务标记
任务标记可以帮助查看任务情况(可标记多次):
WorkRequest request =
new OneTimeWorkRequest.Builder(MyWork.class)
.addTag("tag")
.build();//添加标记为 tag
WorkInfo info = WorkManager.getWorkInfosByTag(String tag);//返回含有该 tag 的 WorkInfo
info.getTags();//获取 Work 的所有 tag
WorkManager.cancelAllWorkByTag(String tag);//取消含有 tag 标记的所有任务请求
- 向 Worker 传入数据并获取
WorkRequest.setInputData(Data data) 传入数据,Worker.getInputData.getXXX(String key)获取数据。
// 自定义 Worker 并获取数据
public class MyWorker extends Worker {
public MyWorker(Context appContext, WorkerParameters workerParams) {
super(appContext, workerParams);
}
@NonNull
@Override
public Result doWork() {
String msg = getInputData().getString("msg");
if(msg == null) {
return Result.failure();
}
//使用数据进行操作
return Result.success();
}
}
// 创建请求并传入数据
WorkRequest myUploadWork =
new OneTimeWorkRequest.Builder(UploadWork.class)
.setInputData(
new Data.Builder()
.putString("msg", "这是信息值")
.build()
)
.build();
Data 以 ket-valus 形式存储,获取使用 key 即可。