Android标准化项目架构:MVVM+Jectpack
助力研发,本篇将对Jectpack 中的WorkManager进行简要分析
文章目录
1.WorkManager描述:
应用程序不可能总是在前台,但是此时你还要确保重要任务的执行,就可以放置在后台执行,那么WorkManager就可以就能发挥重要作用了。
WorkManger是Android Jetpack提供执行后台任务管理的组件,它适用于需要保证系统即使应用程序退出也会运行的任务,WorkManager API可以轻松指定可延迟的异步任务以及何时运行它们,这些API允许您创建任务并将其交给WorkManager立即运行或在适当的时间运行。
WorkManager根据设备API级别和应用程序状态等因素选择适当的方式来运行任务。
如果WorkManager在应用程序运行时执行您的任务之一,WorkManager可以在您应用程序进程的新线程中运行您的任务。
如果您的应用程序未运行,WorkManager会选择一种合适的方式来安排后台任务 - 具体取决于设备API级别和包含的依赖项,WorkManager可能会使用 JobScheduler,Firebase JobDispatcher或AlarmManager。
2.WorkManager作用
- 确保重要的后台任务一定会被执行,后台任务(例如:非及时性的 (请求服务器 及时性) 上传,下载,同步数据 等)
- 内部对电量进行了优化,不需要我们去处理电量优化了
- API 14 到 最新版本,都可以使用WorkManager来管你你的后台任务
- 注意:WorkManager不能做保活操作
- 调度,管理,执行的后台任务的场景,通常是是可延迟的后台任务
3.WorkManager的各个角色分析
3.1.Worker
Worker是一个抽象类,用于声明一个任务,必须重写doWork()方法,这个方法执行的任务是子线程。可以返回一个Result结果。
3.2.WorkRequest
可以这样理解,执行一项单一的任务,WorkRequest对象必须指定Work执行的任务,WorkRequest都有一个自动生成的唯一ID,可以使用ID执行取消
排队任务 或 获取任务状态等操作。
WorkRequest是一个抽象的类,系统默认实现子类:
-
OneTimeWorkRequest:执行单次任务
-
PeriodicWorkRequest:执行循环任务,注意时间周期的设置,不小于15分钟,小于15分钟系统会默认是15分钟,为了电量考虑的,不允许频繁执行任务。
3.3.Constraints
指定对任务运行时间的限制(任务约束);使用Constraints.Builder创建Constraints对象 ,并传递给WorkRequest.Builder。
约束条件有:
- setRequiredNetworkType:网络连接设置
- setRequiresBatteryNotLow:是否为低电量时运行 默认false
- setRequiresCharging:是否要插入设备(接入电源),默认false
- setRequiresDeviceIdle:设备是否为空闲,默认false
- setRequiresStorageNotLow:设备可用存储是否不低于临界阈值
3.4.WorkManager
WorkManager:排队和管理工作请求;将WorkRequest 对象传递WorkManager的任务队列,如果未指定任何约束, WorkManager立即运行任务。
3.5WorkStatus:
5WorkStatus包含有关特定任务的信息;可以使用LiveData保存 WorkStatus对象,监听任务状态;如LiveData
4.WorkManager给任务传参数并回调结果
声明一个task任务
public class Work2 extends Worker {
private WorkerParameters mWorkerParameters;
public MainWork2(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
mWorkerParameters = workerParams;
}
@NonNull
@Override
public Result doWork() {
String name1 = Thread.currentThread().getName();
Log.d("lpf", "MainWork2 doWork start--------Thread.currentThread()="+name1);
String name = mWorkerParameters.getInputData().getString("name");
Log.d("lpf", "MainWork2 接收到传递过来的数据name="+name);
Data data = new Data.Builder().putString("level", "封号斗罗").build();
//返回数据,数据存放在状态机里边,页面不可见的情况不需要处理
return Result.success(data);
}
}
在activity中添加任务执行
/**
* 来回传递数据 ,通过LiveData回传的数据
* @param view
*/
public void testWorkManager(View view) {
Data data = new Data.Builder().putString("name", "唐三").build();
OneTimeWorkRequest oneTimeWorkRequest=new OneTimeWorkRequest.Builder(Work2.class)
.setInputData(data)
.build();
WorkManager.getInstance(this).
getWorkInfoByIdLiveData(oneTimeWorkRequest.getId()).observe(this,
new Observer<WorkInfo>() {
@Override
public void onChanged(WorkInfo workInfo) {
String name = Thread.currentThread().getName();
Log.d("lpf", "状态:" + workInfo.getState().name()+" Thread.currentThread()="+name);
if (workInfo.getState().isFinished()){
String level = workInfo.getOutputData().getString("level");
Log.d("lpf", "从work返回的数据是:" + level);
}
}
});
WorkManager.getInstance(this).enqueue(oneTimeWorkRequest);
}
传递String类型的参数,并回调一个level结果。
5.WorkManager执行多个任务
public void testWorkManager(View view) {
OneTimeWorkRequest oneTimeWorkRequest3 = new OneTimeWorkRequest.Builder(Work3.class).build();
OneTimeWorkRequest oneTimeWorkRequest4 = new OneTimeWorkRequest.Builder(Work4.class).build();
OneTimeWorkRequest oneTimeWorkRequest5 = new OneTimeWorkRequest.Builder(Work5.class).build();
OneTimeWorkRequest oneTimeWorkRequest6 = new OneTimeWorkRequest.Builder(Work6.class).build();
WorkManager.getInstance(this).beginWith(oneTimeWorkRequest3)
.then(oneTimeWorkRequest4)
.then(oneTimeWorkRequest5)
.then(oneTimeWorkRequest6).enqueue();
}
通过beginWith方法和then方法,执行一组任务。
6.WorkManager轮询任务
//多次/循环/轮询 任务
public void testWorkManager(View view) {
PeriodicWorkRequest pro = new PeriodicWorkRequest.Builder(MainWork3.class, 20, TimeUnit.MINUTES).build();
WorkManager.getInstance(this).getWorkInfoByIdLiveData(pro.getId()).
observe(this, new Observer<WorkInfo>() {
@Override
public void onChanged(WorkInfo workInfo) {
Log.d("lpf", "状态:" + workInfo.getState().name());
if (workInfo.getState().isFinished()) {
Log.d("lpf", "状态:isFinished=true 后台任务执行完成");
}
}
});
WorkManager.getInstance(this).enqueue(pro);
}
PeriodicWorkRequest声明轮询任务,注意:不能小于15分钟,否则默认修改成15分钟。
7.WorkManager带约束条件的任务
public void testWorkManager(View view) {
Constraints constraints = new Constraints.Builder().
setRequiredNetworkType(NetworkType.CONNECTED)
//充电中
.setRequiresCharging(true)
//空闲的时候
.setRequiresDeviceIdle(true)
.build();
// 请求对象
OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(MainWork4.class)
// Request 关联约束条件
.setConstraints(constraints)
.build();
WorkManager.getInstance(this).enqueue(oneTimeWorkRequest);
}
通过Constraints这个增加约束,上面这个任务在
联网状态、充电的时候、空闲的时候才会执行,非常适合Log日志的上传任务等。