JetPack--WorkManager
2023-04-18 12:33:14 时间
WorkManager是用于后台执行任务的工具,相比于Service、JobSchedule等,它拥有很低的能耗,但是它不是立即执行任务的,对于一些不需要及时完成的任务,使用WorkManager是一个很好的选择
WorkManager内部使用了数据库,所以能保证任务一定会执行。WorkManager的兼容性也很好,最低支持api14,api23以前,WorkManager内部是使用了JobSchedule,23以后使用的是AlarmManager+BroadCastReceiver
使用WorkManager需要添加gradle依赖:
implementation 'androidx.work:work-runtime:2.5.0'
1.使用WorkManager
定义Work类,继承Worker,doWork方法需要返回一个Result的结果,有成功、重试、失败:
package com.aruba.workmanager;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
/**
* Created by aruba on 2021/9/15.
*/
public class MyWork extends Worker {
private static final String TAG = MyWork.class.getSimpleName();
public MyWork(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
@NonNull
@Override
public Result doWork() {
Log.i(TAG,"doWork");
return Result.success();
}
}
在适当的地方,将任务入队:
//设置条件
Constraints constraints = new Constraints.Builder()
//NetworkType.CONNECTED:需要有网络
//NetworkType.NOT_REQUIRED:不需要网络
//NetworkType.NOT_ROAMING:非漫游网络
//NetworkType.METERED:计费网络下执行(流量)
//NetworkType.UNMETERED:不计费网络(wifi)
.setRequiredNetworkType(NetworkType.NOT_REQUIRED)
// .setRequiresBatteryNotLow(true)//不在低电量
// .setRequiresCharging(true)//充电时执行
// .setRequiresStorageNotLow(true)//不在低存储空间
// .setRequiresDeviceIdle(true)//不在待机 api23
.build();
//配置任务
OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(MyWork.class)
.setConstraints(constraints)
//设置延迟
.setInitialDelay(5, TimeUnit.SECONDS)
.build();
//任务入队
WorkManager.getInstance(this).enqueue(workRequest);
2.指数退避策略
我们也可以为任务配置指数退避策略,当任务需要retry时,它会根据给定的退避时间指数增长,列如:退避时间为2,重试的时间间隔为:2,4,8...
//配置任务
OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(MyWork.class)
.setConstraints(constraints)
//设置延迟
.setInitialDelay(5, TimeUnit.SECONDS)
//指数退避策略
.setBackoffCriteria(BackoffPolicy.LINEAR,2,TimeUnit.SECONDS)
.build();
3.为任务配置TAG
//配置任务
OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(MyWork.class)
.setConstraints(constraints)
//设置延迟
.setInitialDelay(5, TimeUnit.SECONDS)
//指数退避策略
.setBackoffCriteria(BackoffPolicy.LINEAR,2,TimeUnit.SECONDS)
//设置tag
.addTag("work1")
.build();
4.监听任务状态
使用workManager对任务状态进行监听
//添加任务监听
workManager.getWorkInfoByIdLiveData(workRequest.getId()).observe(this, new Observer<WorkInfo>() {
@Override
public void onChanged(WorkInfo workInfo) {
Log.i("WorkInfo", workInfo.toString());
}
});
5.取消任务
//取消任务
workManager.cancelWorkById(workRequest.getId());
6.参数传递
参数传递分成两方面,一个是创建任务时传入参数,一个是执行任务时传递参数 使用Data在创建任务时传入参数:
//传入参数
Data data = new Data.Builder()
.putString("createTask", "createTask")
.build();
//配置任务
OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(MyWork.class)
.setConstraints(constraints)
//设置延迟
.setInitialDelay(5, TimeUnit.SECONDS)
//指数退避策略
.setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.SECONDS)
//设置tag
.addTag("work1")
//传入参数
.setInputData(data)
.build();
在我们自定义的Work中,doWork方法内可以获取到创建时传递的参数,并且传递新的参数
@NonNull
@Override
public Result doWork() {
Log.i(TAG,"doWork");
//获取参数
String createTask = getInputData().getString("createTask");
Log.i(TAG,"createTask");
//传递新参数
Data data = new Data.Builder()
.putString("doWork", "doWork complete")
.build();
return Result.success(data);
}
可以在监听任务状态时,获取完成任务的参数:
//添加任务监听
workManager.getWorkInfoByIdLiveData(workRequest.getId()).observe(this, new Observer<WorkInfo>() {
@Override
public void onChanged(WorkInfo workInfo) {
Log.i("WorkInfo", workInfo.toString());
if (workInfo != null && workInfo.getState() == WorkInfo.State.SUCCEEDED) {
String doWork = workInfo.getOutputData().getString("doWork");
Log.i("WorkInfo", doWork);
}
}
});
7.周期性任务
使用PeriodicWorkRequest对象,并且指定的时间不能低于15分钟
//周期性任务
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest
.Builder(MyWork.class, Duration.ofMinutes(15))
.build();
}
8.任务链与任务组合
任务也是可以链式执行的:
OneTimeWorkRequest aWork = new OneTimeWorkRequest.Builder(AWork.class)
.build();
OneTimeWorkRequest bWork = new OneTimeWorkRequest.Builder(BWork.class)
.build();
//先执行A再执行B
workManager.beginWith(aWork).then(bWork).enqueue();
任务组合,使用WorkContinuation的combine方法来组合WorkContinuation集合执行,可以使用then方法指定延后执行的任务:
OneTimeWorkRequest aWork = new OneTimeWorkRequest.Builder(AWork.class)
.build();
OneTimeWorkRequest bWork = new OneTimeWorkRequest.Builder(BWork.class)
.build();
OneTimeWorkRequest cWork = new OneTimeWorkRequest.Builder(CWork.class)
.build();
OneTimeWorkRequest dWork = new OneTimeWorkRequest.Builder(DWork.class)
.build();
OneTimeWorkRequest eWork = new OneTimeWorkRequest.Builder(EWork.class)
.build();
//先A再B
WorkContinuation workContinuation1 = workManager.beginWith(aWork).then(bWork);
//先C再D
WorkContinuation workContinuation2 = workManager.beginWith(cWork).then(dWork);
List<WorkContinuation> workContinuations = new ArrayList<>();
workContinuations.add(workContinuation1);
workContinuations.add(workContinuation2);
//最后执行E
WorkContinuation.combine(workContinuations).then(eWork).enqueue();
Demo地址:https://gitee.com/aruba/my-jetpack-application.git
相关文章
- 【技术种草】cdn+轻量服务器+hugo=让博客“云原生”一下
- CLB运维&运营最佳实践 ---访问日志大洞察
- vnc方式登陆服务器
- 轻松学排序算法:眼睛直观感受几种常用排序算法
- 十二个经典的大数据项目
- 为什么使用 CDN 内容分发网络?
- 大数据——大数据默认端口号列表
- Weld 1.1.5.Final,JSR-299 的框架
- JavaFX 2012:彻底开源
- 提升as3程序性能的十大要点
- 通过凸面几何学进行独立于边际的在线多类学习
- 利用行动影响的规律性和部分已知的模型进行离线强化学习
- ModelLight:基于模型的交通信号控制的元强化学习
- 浅谈Visual Source Safe项目分支
- 基于先验知识的递归卡尔曼滤波的代理人联合状态和输入估计
- 结合网络结构和非线性恢复来提高声誉评估的性能
- 最佳实践丨云开发CloudBase多环境管理实践
- TimeVAE:用于生成多变量时间序列的变异自动编码器
- 具有线性阈值激活的神经网络:结构和算法
- 内网渗透之横向移动 -- 从域外向域内进行密码喷洒攻击