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@Overridepublic 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>() {@Overridepublic 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>>() {@Overridepublic 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)已经能够满足大多数情况下的需求。