WorkManager是什么?它是谷歌提供的Architecture Components 架构组件的库中的其中一个库,WorkManager有什么用?官方解释如下:
Note: WorkManager is intended for tasks that require a guarantee that the system will run them even if the app exits, like uploading app data to a server. It is not intended for in-process background work that can safely be terminated if the app process goes away; for situations like that, we recommend using ThreadPools.
也就是说这个库是用来做一些在你应用进程停止的时候或突然退出的时候不得不做一些事情的时候,比如上传文件的时候或者下载app的时候,如果为了防止应用突然停止,为了防止你下载文件不全的情况出现,或者你想做在某种情况下在后台执行任务(比如在有网的时候执行),那么你可以利用这个库。这个库是帮你在特定条件下选择使用JobScheduler
, Firebase JobDispatcher, or AlarmManager,而让开发者专注于逻辑开发,而不用关心到底该选择哪个api来使用,并且你在执行异步任务的时候可以观察任务的执行状态,来做一些其他的处理。
下面来看看这个库怎么用?
首先你需要在根build.gradle中加入
allprojects {
repositories {
jcenter()
google()
}
}
然后在项目中的build.gradle中加入
dependencies {
def work_version = "1.0.0-alpha05"
implementation "android.arch.work:work-runtime:$work_version" // use -ktx for Kotlin
// optional - Firebase JobDispatcher support
implementation "android.arch.work:work-firebase:$work_version"
这里注意你用的gradle构建工具的版本。
接下来来看一看这个库的api是怎么使用的?
1、重写Worker类的doWork()方法
public class WorkerTyou extends Worker {
@NonNull
@Override
public Result doWork() {
//你要做的工作
Log.i("huoying","doWork");
//返回值
/**
* Result.FAILURE任务失败
Result.SUCCESS 任务成功
Result.RETRY 任务出现故障
*/
return null;
}
在里面写上你要处理的代码,也就是你要做的工作,顾名思义,谷歌起名为Worker。
2、选择Work请求(OneTimeWorkRequest(只执行一次任务的请求类),
PeriodicWorkRequest(可以执行多次任务的请求,类似闹钟)
)
//只执行一次任务
OneTimeWorkRequest compressionWork =
new OneTimeWorkRequest.Builder(WorkerTyou.class)
.build();
//执行多次任务,每隔12个小时执行一次
PeriodicWorkRequest.Builder photoCheckBuilder =
new PeriodicWorkRequest.Builder(WorkerTyou.class, 12,
TimeUnit.HOURS);
//执行任务
WorkManager.getInstance().enqueue(compressionWork);
3、监听任务执行状态
WorkManager.getInstance().getStatusById(compressionWork.getId())
.observe(this, new Observer<WorkStatus>() {
@Override
public void onChanged(@Nullable WorkStatus workStatus) {
/* *//**
* 根据workStatus.getState()状态来做一些事情
/**
* 正在排队的状态
*//*
ENQUEUED,
*//**
* 任务正在运行
*//*
RUNNING,
*//**
* 任务运行成功
*//*
SUCCEEDED,
*//**
* 任务运行失败
*//*
FAILED,
*//**
*前面的任务运行失败
*//*
BLOCKED,
*//**
* 任务被取消
*//*
CANCELLED;*/
}
});
4、限制任务执行条件Constraints(例如设备空闲的时候运行或者链接电源的时候使用等)
Constraints
//只执行一次任务
Constraints myConstraints = new Constraints.Builder()
//手机设备空闲的时候使用
.setRequiresDeviceIdle(true)
//手机接通电源的时候使用
.setRequiresCharging(true)
//网络连接的时候执行任务
.setRequiredNetworkType(NetworkType.CONNECTED)
//电池电量低于临界水平不可用
.setRequiresBatteryNotLow(true)
//可用存储不能低于临界值
.setRequiresStorageNotLow(true)
.build();
OneTimeWorkRequest compressionWork =
new OneTimeWorkRequest.Builder(WorkerTyou.class).setConstraints(myConstraints)
.build();
5、按顺序执行任务
WorkManager.getInstance()
.beginWith(workA)
// Note: WorkManager.beginWith() returns a
// WorkContinuation object; the following calls are
// to WorkContinuation methods
.then(workB) // FYI, then() returns a new WorkContinuation instance
.then(workC)
.enqueue();
先执行任务a再执行任务b再执行任务c。
WorkManager.getInstance()
// First, run all the A tasks (in parallel):
.beginWith(workA1, workA2, workA3)
// ...when all A tasks are finished, run the single B task:
.then(workB)
// ...then run the C tasks (in any order):
.then(workC1, workC2)
.enqueue();
同时执行workA1、workA2、workA3,然后执行workB,再同时执行workC1和workC2.
6、特殊顺序处理WorkContinuation
如图执行这样的顺序应该怎么处理:
WorkContinuation chain1 = WorkManager.getInstance()
.beginWith(workA)
.then(workB);
WorkContinuation chain2 = WorkManager.getInstance()
.beginWith(workC)
.then(workD);
WorkContinuation chain3 = WorkContinuation
.combine(chain1, chain2)
.then(workE);
chain3.enqueue();
7、为请求设置tag以方便获取任务执行'状态和取消
OneTimeWorkRequest cacheCleanupTask =
new OneTimeWorkRequest.Builder(MyCacheCleanupWorker.class)
.setConstraints(myConstraints)
.addTag("cleanup")
.build();
8、执行任务传值
setInputData
//传值
Data myData = new Data.Builder()
// We need to pass three integers: X, Y, and Z
.putInt(KEY_X_ARG, 42)
.putInt(KEY_Y_ARG, 421)
.putInt(KEY_Z_ARG, 8675309)
// ... and build the actual Data object:
.build();
// ...then create and enqueue a OneTimeWorkRequest that uses those arguments
OneTimeWorkRequest mathWork = new OneTimeWorkRequest.Builder(MathWorker.class)
.setInputData(myData)
.build();
WorkManager.getInstance().enqueue(mathWork);
//接收值
WorkManager.getInstance().getStatusById(mathWork.getId())
.observe(lifecycleOwner, status -> {
if (status != null && status.getState().isFinished()) {
int myResult = status.getOutputData().getInt(KEY_RESULT,
myDefaultValue));
// ... do something with the result ...
}
});