2018年Google I/O大会上推出了一个新的包Jetpack,其中包含了几个类WorkManager、Paging、Navigation 以及 Slices.其中WorkManager就是用来替换之前的Jobschedule,它可以管理一个任务,使任务在特定条件下执行,可以单次和循环执行.还可以设置延时执行等一系列功能.
implementation "android.arch.work:work-firebase:1.0.0-alpha08"
androidTestImplementation "android.arch.work:work-testing:1.0.0-alpha08"
注意:alpha09版本将Worker类定义为弃用类,暂时没有找到替代类
(1)创建worker类
public class TestWorker extends Worker {
private String TAG = "test";
@NonNull
@Override
public Result doWork() {
String data = getInputData().getString("workerData");
Log.d(TAG,"doWork:"+data);
return Result.SUCCESS;
}
}
(2)通过WorkManager启动Worker
import android.annotation.TargetApi;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.util.concurrent.TimeUnit;
import androidx.work.Constraints;
import androidx.work.Data;
import androidx.work.OneTimeWorkRequest;
import androidx.work.PeriodicWorkRequest;
import androidx.work.WorkManager;
public class MainActivity extends AppCompatActivity {
@TargetApi(Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//约束条件 setRequiredNetworkType在特定网络下执行
Constraints mConstraints = new Constraints.Builder()
.setRequiresBatteryNotLow(true)//不在电量不足时执行
.setRequiresCharging(true)//在充电时执行
.setRequiresStorageNotLow(true)//不在存储容量不足时执行
.setRequiresDeviceIdle(true)//在待机状态执行
.build();
//传入参数
Data data = new Data.Builder().putString("workerData","helloWorld").build();
//构造只执行一次的worker
OneTimeWorkRequest testWorker = new OneTimeWorkRequest.Builder(TestWorker.class)
.setInputData(data)
.setInitialDelay(5,TimeUnit.SECONDS) //延时执行worker
.setConstraints(mConstraints).build();
//重复执行的worker
// PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(TestWorker.class,15,
// TimeUnit.SECONDS).setConstraints(mConstraints)
// .setInputData(data).build();
//放入任务队列
WorkManager.getInstance().enqueue(testWorker);
//安顺序执行worker
// WorkManager.getInstance().beginWith(testWorker).then(testWorker).enqueue();
}
}
(3)按顺序执行Worker
WorkManager.getInstance().beginWith(A).then(B).enqueue(); //按顺序逐个执行
WorkManager.getInstance().beginWith(A,B).then(C).enqueue();//A,B同时执行,然后执行C
(4)按任务链执行
任务链可以设置多个任务线不同的执行顺序
//同时执行任务链1和2,执行完成后执行E
WorkContinuation workContinuation1 = WorkManager.getInstance().beginWith(A).then(B);
WorkContinuation workContinuation2 = WorkManager.getInstance().beginWith(C).then(D);
WorkContinuation workContinuation3 = WorkContinuation.combine(workContinuation1,workContinuation2).then(E);
workContinuation3.enqueue();
(5)为Worker设置返回数据
通过 setOutputData()设置返回结果,我们需要通过WorkManager来设置订阅,根据任务的id来订阅任务的状态改变,就可以获取到返回值.
public class TestWorker extends Worker {
private String TAG = "test";
@NonNull
@Override
public Result doWork() {
String data = getInputData().getString("workerData");
Log.d(TAG,"doWork:"+data);
Data responseData = new Data.Builder().putString("response","ok").build();
setOutputData(responseData);
return Result.SUCCESS;
}
}
(6)通过WorkManager订阅返回数据
通过Id来订阅任务的状态改变,可以判断状态类型,只对某些状态进行处理,状态类型包括:ENQUEUED(开始执行),RUNNING(正在运行),SUCCEEDED(任务已经完成),FAILED(任务已经完成,但是任务失败),BLOCKED(任务被阻塞,还未完成),CANCELLED(任务被取消).
//订阅返回数据
WorkManager.getInstance()
.getStatusById(testWorker.getId())
.observeForever(new Observer<WorkStatus>() {
@Override
public void onChanged(@Nullable WorkStatus workStatus) {
Data response = workStatus.getOutputData();
Log.d("test","response:"+response.getString("response"));
}
});
(7)取消Worker
WorkManager.getInstance().cancelWorkById(testWorker.getId());
通过这个方法启动woker时需要制定一个workName,当任务队列中已经存在该任务时,你可以制定是否要替换,保持或者追加新任务.通过ExistingWorkPolicy设置以哪种方式处理相同name的任务
(1)调用方法
/** @param uniqueWorkName 一个任务名称
* @param existingPeriodicWorkPolicy 处理同名任务的方式
*/ @param periodicWork 可以传入多个单次执行的任务
public final @NonNull WorkContinuation beginUniqueWork(
@NonNull String uniqueWorkName,
@NonNull ExistingWorkPolicy existingWorkPolicy,
@NonNull OneTimeWorkRequest... work) {
return beginUniqueWork(uniqueWorkName, existingWorkPolicy, Arrays.asList(work));
}
/** @param uniqueWorkName 一个任务名称
* @param existingPeriodicWorkPolicy 处理同名任务的方式
*/ @param work 多个单次执行的任务列表
public abstract @NonNull WorkContinuation beginUniqueWork(
@NonNull String uniqueWorkName,
@NonNull ExistingWorkPolicy existingWorkPolicy,
@NonNull List<OneTimeWorkRequest> work);
(2)ExistingWorkPolicy的类型