学习目标:
JetPack之WorkManager使用标
学习内容:
workManager
旨在用于延迟运行并且再应用退出或设备重启必须能够可靠运行的任务。
引入配置
implementation 'androidx.work:work-runtime:2.3.4'
三大概念
- Worker
我们要执行的具体任务。需要继承Worker,重写doWork方法,然后在里面写具体的逻辑。 - WorkRequest
上面的Worker是定义了我们要在后台的任务,而这个类是对Worker的包装。
下面两个都是继承了WorkRequest
OneTimeWorkRequest
: 只执行一次的任务
PeriodicWorkRequest
: 重复执行的任务(重复间隔大于15分钟) - WorkManager
是对WorkRequest的管理类。
单任务
首先我们先定义我们要做什么。
public class MyWorker extends Worker{
private Context mContext;
//任务携带参数
private WorkerParameters workerParameters;
public MyWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
this.mContext = context;
this.workerParameters = workerParams;
}
@NonNull
@Override
public Result doWork() {
//接受传第过来的参数 这里的data与MainActivity的data 需要一致
String data = workerParameters.getInputData().getString("data");
//返回处理的结果
Data outData = new Data.Builder().putString("result","来自worker处理后的结果").build();
@SuppressLint("RestrictedApi")
Result.Success success = new Result.Success(outData);
return success;
}
}
然后需要包装这个请求
OneTimeWorkRequest oneTimeWorkRequest;
//传递给Work的参数
Data sendData = new Data.Builder().putString("data", "来自MainActivity的数据").build();
//初始化请求对象request
oneTimeWorkRequest = new OneTimeWorkRequest.Builder(MyWorker.class).setInputData(sendData).build();
//添加回调更新
WorkManager.getInstance(MainActivity.this).getWorkInfoByIdLiveData(oneTimeWorkRequest.getId()).observe(this, new Observer<WorkInfo>() {
@Override
public void onChanged(WorkInfo workInfo) {
//注意这个方法会回调多次
//要加这个判断
if(workInfo.getState().isFinished()){
//执行完成的处理
//接受worker返回的结果
//这里的result与MMyWorker的result 需要一致
String result = workInfo.getOutputData().getString("result");
}
}
});
接下来就是把请求添加到请求队列
//添加到任务队列
WorkManager.getInstance(this).enqueue(oneTimeWorkRequest);
以上就是构建一次任务的步骤了。
多任务
//构建三个不同的请求
OneTimeWorkRequest oneTimeWorkRequest1 = new OneTimeWorkRequest.Builder(MyWorker1.class).build();
OneTimeWorkRequest oneTimeWorkRequest2 = new OneTimeWorkRequest.Builder(MyWorker2.class).build();
OneTimeWorkRequest oneTimeWorkRequest3 = new OneTimeWorkRequest.Builder(MyWorker3.class).build();
//想必下面大家应该都懂得 oneTimeWorkRequest1->oneTimeWorkRequest2->oneTimeWorkRequest3
WorkManager.getInstance(this).beginWith(oneTimeWorkRequest1)
.then(oneTimeWorkRequest2)
.then(oneTimeWorkRequest3)
.enqueue();
循环任务
//这里注意在 20 的地方如果传入小于15的数字,就依然是15 也就是说最小任务循环间隔为15分钟
PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(MyWorker.class,20, TimeUnit.SECONDS).build();
WorkManager.getInstance(this).enqueue(periodicWorkRequest);
这里可以简单看一下为什么最小间隔15分钟?
public final class PeriodicWorkRequest extends WorkRequest {
/**
* The minimum interval duration for {@link PeriodicWorkRequest} (in milliseconds).
*/
@SuppressLint("MinMaxConstant")
public static final long MIN_PERIODIC_INTERVAL_MILLIS = 15 * 60 * 1000L; // 15 minutes.
/**
* The minimum flex duration for {@link PeriodicWorkRequest} (in milliseconds).
*/
@SuppressLint("MinMaxConstant")
public static final long MIN_PERIODIC_FLEX_MILLIS = 5 * 60 * 1000L; // 5 minutes.
.....
public Builder(
@NonNull Class<? extends ListenableWorker> workerClass,
long repeatInterval,
@NonNull TimeUnit repeatIntervalTimeUnit) {
super(workerClass);
mWorkSpec.setPeriodic(repeatIntervalTimeUnit.toMillis(repeatInterval));
}
.....
}
public final class WorkSpec {
......
public void setPeriodic(long intervalDuration) {
//如果小于15minutes
if (intervalDuration < MIN_PERIODIC_INTERVAL_MILLIS) {
Logger.get().warning(TAG, String.format(
"Interval duration lesser than minimum allowed value; Changed to %s",
MIN_PERIODIC_INTERVAL_MILLIS));
//则赋值15minutes
intervalDuration = MIN_PERIODIC_INTERVAL_MILLIS;
}
setPeriodic(intervalDuration, intervalDuration);
}
.....
}
条件任务
意思就是满足某些条件,后台的任务(worker)才会执行(比如连接网络,插入电源,cpu空闲时)才会执行的任务。
Constraints constraints = new Constraints.Builder()
//有网路
.setRequiredNetworkType(NetworkType.CONNECTED)
//充电中
.setRequiresCharging(true)
//cpu空闲时
.setRequiresDeviceIdle(true)
//电池
.setRequiresBatteryNotLow(true)
//可用存储是否不低于最小值
.setRequiresStorageNotLow(true)
.build();
OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(MyWorker.class)
.setConstraints(constraints)
.build();
WorkManager.getInstance(this).enqueue(oneTimeWorkRequest);