适用场景
任务无需立马执行,或者任务可以在 APP 退出之后执行。
运用实例
- 定期向服务器上传 APP 日志
- 定时同步服务端信息
优点
- 优化了电池续航问题
- 工作约束可以明确定义工作运行的最佳条件
- 灵活的重试政策和指数退避政策
- 工作链,可处理多任务且不同顺序执行
引用
dependencies {
def work_version = "2.5.0"
// (Java only)
implementation "androidx.work:work-runtime:$work_version"
// Kotlin + coroutines
implementation "androidx.work:work-runtime-ktx:$work_version"
// optional - RxJava2 support
implementation "androidx.work:work-rxjava2:$work_version"
// optional - GCMNetworkManager support
implementation "androidx.work:work-gcm:$work_version"
// optional - Test helpers
androidTestImplementation "androidx.work:work-testing:$work_version"
// optional - Multiprocess support
implementation "androidx.work:work-multiprocess:$work_version"
}
简单实例
Build.gradle
在 dependencies 中引入 workmanager
//workManager
implementation "androidx.work:work-runtime:2.5.0"
LogWork
继承 Worker,重写 doWork()方法,根据情况返回对应 result 的值。
package com.elaine.testworkmanager;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
/**
* 日志任务
* author: elaine
* date: 2021/7/14
*/
public class LogWork extends Worker {
public LogWork(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
@NonNull
@Override
public Result doWork() {
Log.e("doWork", "日志任务执行了");
return Result.success();
}
}
MainActivity
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.work.Constraints;
import androidx.work.NetworkType;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startLogWork();
}
private void startLogWork() {
//设置触发条件
Constraints constraints = new Constraints.Builder()
//对网络没有要求
.setRequiredNetworkType(NetworkType.NOT_REQUIRED)
.build();
//单次工作请求
OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(LogWork.class)
//设置触发条件
.setConstraints(constraints)
.build();
//任务manager
WorkManager.getInstance(this).enqueue(oneTimeWorkRequest);
}
}
运行结果
Worker
自定义工作,继承 Worker,增加构造方法,重写 doWork()方法。
| 返回值 | 意义 |
|---|---|
| Result.success() | 工作成功完成 |
| Result.failure() | 工作失败 |
| Result.success(Data) | 工作成功完成并传递数据 |
| Result.failure(Data) | 工作失败并传递数据 |
| Result.retry() | 工作失败,应根据其重试政策在其他时间尝试 |
| 在 doWork 方法中获取数据 |
@NonNull
@Override
public Result doWork() {
//获取数据
String inputData = getInputData().getString("input_data");
Log.d("inputData",inputData);
//任务执行完之后,返回数据
Data outputData = new Data.Builder()
.putString("output_data", "执行成功")
.build();
return Result.success(outputData);
}
Constraints
用于配置触发条件,即工作约束。
Constraints constraints = new Constraints.Builder()
//.setRequiresBatteryNotLow(true) //电量不足不执行
//.setRequiresCharging(true) //在充电时执行
//.setRequiresStorageNotLow(true) //存储容量不足时不执行
//.setRequiresDeviceIdle(true) //在待机状态下执行 调用需要API级别最低为23
//.setRequiredNetworkType(NetworkType.NOT_REQUIRED)
// NetworkType.NOT_REQUIRED:对网络没有要求
// NetworkType.CONNECTED:网络连接时执行
// NetworkType.UNMETERED:不计费的网络比如WIFI下执行
// NetworkType.NOT_ROAMING:非漫游网络状态执行
// NetworkType.METERED:计费网络比如3G,4G下执行
.build();
WorkRequest
定义工作运行方式和时间。
- 设置触发条件
//设置触发条件
.setConstraints(constraints)
- 延迟执行
//设置延迟执行
.setInitialDelay(5, TimeUnit.SECONDS)
- 退避政策
LINEAR----重试间隔都会增加约 10 秒,例如:20 秒、30 秒、40 秒
EXPONENTIAL----指数级增加时间间隔,例如:20 秒、40 秒、80 秒
//指数退避策略
.setBackoffCriteria(BackoffPolicy.LINEAR, Duration.ofSeconds(10))
- 标记工作
方便取消工作或者观察工作。
//设置tag标签
.addTag("workRequest")
- 传递参数
Data inputData = new Data.Builder()
.putString("input_data","data")
.build();
//参数传递
.setInputData(inputData)
子类 OneTimeWorkRequest
调用一次性工作
WorkRequest uploadWorkRequest =
new OneTimeWorkRequest.Builder(MyWork.class)
// Additional configuration
.build();
子类 PeriodicWorkRequest
调度定期工作
注意:可以定义的最短重复间隔是 15 分钟
PeriodicWorkRequest saveRequest =
new PeriodicWorkRequest.Builder(SaveImageToFileWorker.class, 1, TimeUnit.HOURS)
// Additional configuration
.build();
WorkManager
任务管理器
- 新增工作
WorkManager.getInstance(this).enqueue(workRequest);
- 取消工作
WorkManager.getInstance(this).cancelWorkById(workRequest.getId());
- 观察工作
WorkManager.getInstance(this).getWorkInfoByIdLiveData(workRequest.getId()).observe(this, new Observer<WorkInfo>() {
@Override
public void onChanged(WorkInfo workInfo) {
Log.d("WorkInfo",workInfo.toString());
}
});
链接工作
多个工作按照一定的顺序执行。
WorkManager.getInstance(myContext)
// Candidates to run in parallel
.beginWith(Arrays.asList(plantName1, plantName2, plantName3))
// Dependent work (only runs after all previous work in chain)
.then(cache)
.then(upload)
// Call enqueue to kick things off
.enqueue();