Android WorkManager使用介绍
1. 添加依赖
首先,确保你的项目中包含了WorkManager库。在build.gradle
文件中添加依赖:
dependencies {
def work_version = "2.8.1" // 使用最新版本
implementation "androidx.work:work-runtime:$work_version"
}
然后同步项目以下载依赖。
2. 创建Worker类
创建一个继承自Worker
的类,并重写doWork()
方法。在这个方法里编写你想要执行的任务逻辑。
import androidx.work.Worker;
import androidx.work.WorkerParameters;
public class MyWorker extends Worker {
public MyWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
@NonNull
@Override
public Result doWork() {
// 在这里放置你的异步处理代码
return Result.success(); // 或者 Result.failure() 如果任务失败
}
}
3. 配置和构建WorkRequest
根据任务的需求选择合适的WorkRequest
类型:OneTimeWorkRequest
用于一次性任务,PeriodicWorkRequest
用于周期性任务。你可以设置约束条件(如网络状态)以及输入数据。
import androidx.work.Constraints;
import androidx.work.NetworkType;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;
// 设置约束条件
Constraints constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build();
// 构建一次性任务请求
OneTimeWorkRequest myWorkRequest = new OneTimeWorkRequest.Builder(MyWorker.class)
.setConstraints(constraints)
.build();
4. 调度任务
使用WorkManager
来调度任务。可以通过enqueue()
方法将任务加入队列。
WorkManager.getInstance(context).enqueue(myWorkRequest);
5. 监听任务结果
如果需要监听任务的状态变化或结果,可以使用LiveData
来观察WorkInfo
。
import androidx.lifecycle.Observer;
import androidx.work.WorkInfo;
WorkManager.getInstance(context).getWorkInfoByIdLiveData(myWorkRequest.getId())
.observe(lifecycleOwner, new Observer<WorkInfo>() {
@Override
public void onChanged(WorkInfo workInfo) {
if (workInfo != null && workInfo.getState().equals(WorkInfo.State.SUCCEEDED)) {
// 处理任务成功后的逻辑
} else if (workInfo != null && workInfo.getState().equals(WorkInfo.State.FAILED)) {
// 处理任务失败后的逻辑
}
}
});
6. 取消任务
如果你需要取消已经安排的任务,可以使用WorkManager
提供的取消方法。
WorkManager.getInstance(context).cancelWorkById(myWorkRequest.getId());
注意事项
Worker
类中的doWork()
方法必须是同步的,意味着它会阻塞直到返回。WorkManager
适合用于非即时性的后台任务,对于即时任务应考虑其他方案如Executors
或者HandlerThread
。- 当使用
PeriodicWorkRequest
时,请注意最小间隔时间为15分钟。
WorkManager的高级操作
1. 链式任务(Chaining Work)
有时你需要一个任务完成后立即启动另一个任务。这可以通过beginWith()
、then()
和enqueue()
方法链来实现。
import androidx.work.WorkManager;
import androidx.work.OneTimeWorkRequest;
// 创建两个工作请求
OneTimeWorkRequest workA = new OneTimeWorkRequest.Builder(MyWorkerA.class).build();
OneTimeWorkRequest workB = new OneTimeWorkRequest.Builder(MyWorkerB.class).build();
// 链接任务 A -> B
WorkContinuation continuation = WorkManager.getInstance(context)
.beginWith(workA)
.then(workB);
// 执行链接的任务
continuation.enqueue();
2. 输入输出参数
你可以在不同的Worker
之间传递数据。通过Data
对象可以设置输入参数,并在doWork()
方法中获取这些参数。
import androidx.work.Data;
// 设置输入数据
Data inputData = new Data.Builder()
.putString("KEY_INPUT", "input value")
.build();
// 使用输入数据创建工作请求
OneTimeWorkRequest myWorkRequest = new OneTimeWorkRequest.Builder(MyWorker.class)
.setInputData(inputData)
.build();
// 在Worker中获取输入数据
@Override
public Result doWork() {
String input = getInputData().getString("KEY_INPUT");
// 处理...
return Result.success();
}
// 设置输出数据
return Result.success(
new Data.Builder()
.putString("KEY_OUTPUT", "output value")
.build()
);
3. 周期性任务(Periodic Work)
周期性任务允许你定义每隔一段时间执行一次的任务。需要注意的是,最小周期时间是15分钟。
import androidx.work.PeriodicWorkRequest;
// 创建周期性工作请求,间隔时间为1小时
PeriodicWorkRequest periodicWorkRequest =
new PeriodicWorkRequest.Builder(MyWorker.class, 1, TimeUnit.HOURS)
.build();
// 调度周期性任务
WorkManager.getInstance(context).enqueue(periodicWorkRequest);
4. 监控多个任务的状态
如果你想同时监控多个任务的状态变化,可以使用getWorkInfosForUniqueWorkLiveData()
或getWorkInfosByTagLiveData()
。
import androidx.lifecycle.Observer;
import androidx.work.WorkInfo;
// 观察具有特定标签的任务集合的状态
WorkManager.getInstance(context).getWorkInfosByTagLiveData("my_tag")
.observe(lifecycleOwner, new Observer<List<WorkInfo>>() {
@Override
public void onChanged(List<WorkInfo> list) {
for (WorkInfo info : list) {
if (info.getState().isFinished()) {
// 检查每个任务是否完成并处理结果
}
}
}
});
5. 取消所有工作
如果你想要取消所有的工作,可以调用cancelAllWork()
或者根据唯一的名字取消特定的工作。
// 取消所有工作
WorkManager.getInstance(context).cancelAllWork();
// 根据唯一的名字取消特定的工作
WorkManager.getInstance(context).cancelUniqueWork("unique_name");
// 根据标签取消特定的工作
WorkManager.getInstance(context).cancelAllWorkByTag("tag_name");
6. 工作约束(Constraints)
除了简单的网络连接等条件外,还可以添加更复杂的约束条件,比如存储空间充足、电池电量足够等。
import androidx.work.Constraints;
import androidx.work.NetworkType;
Constraints constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.UNMETERED) // 仅限非计量网络
.setRequiresBatteryNotLow(true) // 电池电量不能过低
.setRequiresStorageNotLow(true) // 存储空间不能不足
.build();
OneTimeWorkRequest constrainedWorkRequest =
new OneTimeWorkRequest.Builder(MyWorker.class)
.setConstraints(constraints)
.build();
7. 自定义调度器(Custom Scheduler)
如果你有特殊需求,例如需要与某些后台服务进行交互,可以考虑实现自定义的Scheduler
接口。但这通常不是必需的,因为默认的JobScheduler
(API 21+)和AlarmManager
(API < 21)已经能够满足大多数情况下的需求。