文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android Jetpack(八)WorkManager

2022-06-06 12:47

关注

一、WorkManager 介绍

        WorkManager 是 Jetpack 组件库的一个组件,负责管理后台任务

        WorkManager API 可以让你更加容易的管理一些后台任务,即使你的应用是退出或者设备重启的状态

        WorkManager 适用于任务的延迟执行,不需要立即执行,并且可以可靠的执行即使应用退出或者设备重启例如:

向后端服务发送日志分析 定期与服务器同步应用程序数据

        WorkManager 不适用于那些在应用进程消失的时候,可以安全被终止的后台任务

      WorkManager和传统 Service 后台任务的区别: WorkManager不会因为应用进程的消失而被终止,即使设备被重启。而 Service 是做不到的。 Service 更加适用于应用内的后台任务。 WorkManager 可以设置延迟执行,不需要马上执行,也就是我们常说的定时任务。 二、WorkManager 核心类

        我们先来看看 WorkManager 相关的几个类:

Worker
任务的执行者,是一个抽象类,需要继承它实现要执行的任务。

WorkRequest
指定让哪个 Woker 执行任务,指定执行的环境,执行的顺序等。
要使用它的子类 OneTimeWorkRequest PeriodicWorkRequest

WorkManager
管理任务请求和任务队列,发起的 WorkRequest 会进入它的任务队列。

WorkStatus
包含有任务的状态和任务的信息,以 LiveData 的形式提供给观察者。

三、WorkManager 使用

1. 导入依赖库

implementation "android.arch.work:work-runtime:1.0.1"

2. 使用 Worker 定义任务


public class UploadLogWorker extends Worker {
    private static final String TAG = "UploadLogWorker";
    public UploadLogWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }
    
    @NonNull
    @Override
    public Result doWork() {
        Log.d(TAG, "doWork()");
        return Result.success();
    }
}

        doWork()方法有三种类型的返回值:

执行成功返回Result.success() 执行失败返回Result.failure() 需要重新执行返回Result.retry()

3. 使用 WorkRequest 配置任务

        通过 WorkRequest 配置我们的任务何时运行以及如何运行

(1)通过 Constraints 设置任务触发条件

        例如,我们可以设置在设备处于充电,网络已连接,且电池电量充足的状态下,才出发我们设置的任务。


Constraints constraints = new Constraints.Builder()
        .setRequiresCharging(true)
        .setRequiredNetworkType(NetworkType.CONNECTED)
        .setRequiresBatteryNotLow(true)
        .build();

(2)将该 Constraints 设置到 WorkRequest

        WorkRequest 是一个抽象类,它有两种实现:

OneTimeWorkRequest:一次性任务  PeriodicWorkRequest:周期性任务

        WorkRequest 还可以设置延迟执行任务。假设你没有设置触发条件,或者当你设置的触发条件符合系统的执行要求,此时,系统有可能立刻执行该任务,但如果你希望能够延迟执行,那么可以通过 setInitialDelay() 方法,延后任务的执行。

       WorkRequest 还可以设置指数退避策略。假如 Worker 线程的执行出现了异常,比如服务器宕机,那么你可能希望过一段时间,重试该任务。那么你可以在 Worker 的 doWork() 方法中返回 Result.retry(),系统会有默认的指数退避策略来帮你重试任务,你也可以通过 setBackoffCriteria() 方法,自定义指数退避策略。


OneTimeWorkRequest uploadWorkRequest = new OneTimeWorkRequest.Builder(UploadLogWorker.class)
        .setConstraints(constraints)//设置触发条件
        .setInitialDelay(10, TimeUnit.SECONDS)  //符合触发条件后,延迟10秒执行
        .setBackoffCriteria(BackoffPolicy.LINEAR, OneTimeWorkRequest.MIN_BACKOFF_MILLIS, TimeUnit.MILLISECONDS)//设置指数退避算法
        .addTag("UploadTag")  //设置Tag
        .build();

 (3)通过 WorkManager 执行任务


WorkManager.getInstance().enqueue(uploadWorkRequest);

        取消任务:

        与观察任务类似的,我们也可以根据Id或者Tag取消某个任务,或者取消所有任务。


WorkManager.getInstance(MainActivity.this).cancelAllWork();
四、WorkManager 拓展 1. 观察任务的状态

        任务在提交给系统后,通过 WorkInfo 获知任务的状态,WorkInfo 包含了任务的 id,tag,以及 Worker 对象传递过来的outputData,以及任务当前的状态。

        有三种方式可以得到 WorkInfo 对象

WorkManager.getWorkInfosByTag() WorkManager.getWorkInfoById() WorkManager.getWorkInfosForUniqueWork()

        如果你希望能够实时获知任务的状态。这三个方法还有对应的LiveData方法。

WorkManager.getWorkInfosByTagLiveData() WorkManager.getWorkInfoByIdLiveData() WorkManager.getWorkInfosForUniqueWorkLiveData()

        通过 LiveData,我们便可以在任务状态发生变化的时候,收到通知。 


WorkManager.getInstance(this).getWorkInfoByIdLiveData(uploadWorkRequest.getId()).observe(MainActivity.this, new Observer()
{
    @Override
    public void onChanged(WorkInfo workInfo)
    {
        Log.d("onChanged()->", "workInfo:"+workInfo);
    }
});
 2. 传递数据

        WorkManager 和 Worker 之间的数据传递通过 Data 对象来完成。

        WorkManager 通过 setInputData() 方法向 Worker 传递数据。


Data inputData = new Data.Builder().putString("input_data", "Hello World!").build();
OneTimeWorkRequest uploadWorkRequest = new OneTimeWorkRequest.Builder(UploadLogWorker.class)
                .setInputData(inputData)
                .build();

        Worker 中接收数据,并在任务执行完成后,向 WorkManager 传递数据。


@Override
public Result doWork()
{
    //接收外面传递进来的数据
    String inputData = getInputData().getString("input_data");
    // 任务执行完成后返回数据
    Data outputData = new Data.Builder().putString("output_data", "Task Success!").build();
    return Result.success(outputData);
}

        WorkManager 通过 LiveData 的 WorkInfo.getOutputData(),得到从 Worker 传递过来的数据。


WorkManager.getInstance(this).getWorkInfoByIdLiveData(uploadWorkRequest.getId()).observe(MainActivity.this, new Observer()
{
    @Override
    public void onChanged(WorkInfo workInfo)
    {
        if (workInfo != null && workInfo.getState() == WorkInfo.State.SUCCEEDED)
        {
            String outputData = workInfo.getOutputData().getString("output_data");
        }
    }
});
 注意:  Data只能用于传递一些小的基本类型数据,且数据最大不能超过10kb。 3. 周期任务

        周期性任务 PeriodicWorkRequest 会按照设定的时间定期执行。与 OneTimeWorkRequest 相比,二者使用起来没有太大差别。

        需要注意的是:周期性任务的间隔时间不能小于15分钟


PeriodicWorkRequest uploadWorkRequest = new PeriodicWorkRequest.Builder(UploadLogWorker.class, 15, TimeUnit.MINUTES)
        .setConstraints(constraints)
        .addTag(TAG)
        .build();
4. 任务链

        如果你有一系列的任务需要顺序执行,那么可以利用 WorkManager.beginWith().then().then()...enqueue() 方法。例如:我们在上传数据之前,需要先对数据进行压缩。


WorkManager.getInstance(this).beginWith(compressWorkRequest).then(uploadWorkRequest).enqueue();

        假设有更复杂的任务链,你还可以考虑使用 WorkContinuation.combine() 方法,将任务链组合起来。


WorkContinuation workContinuation1 =  WorkManager.getInstance(this).beginWith(WorkRequestA).then(WorkRequestB);
WorkContinuation workContinuation2 =  WorkManager.getInstance(this).beginWith(WorkRequestC).then(WorkRequestD);
List taskList = new ArrayList();
taskList.add(workContinuation1);
taskList.add(workContinuation2);
WorkContinuation.combine(taskList).then(WorkRequestE).enqueue();

作者:Fighting_初心


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯