【Jetpack】WorkManager定时任务利器

QuibblerQuibbler 2020-08-10 约 13 分钟 2261 次阅读

定时任务利器:WorkManager库

查看JetPack内容库的时候发现了WorkManager库更新到最新稳定版本2.4.0(2020年8月9号)。WorkManager是Google推出的调度定时任务新技术,官方文档:Docs>Reference>WorkManager">Android Docs>Reference>WorkManager

推荐观看Google技术推广工程师史婧羽小姐姐的WorkManager解说(゜-゜)つロ 干杯~

1、WorkManager

        “使用 WorkManager API 可以轻松地调度那些必须可靠地运行的可延期异步任务。通过这些 API,您可以创建任务并提交给 WorkManager,以便在满足工作约束条件时运行。”

1.1、版本

WorkManager推出已经有两年多了,从2018年5月8号的第一个1.0.0-alpha01版本,最新的稳定版本是2.4.0-rc01。到现在经过66个版本的迭代(截止2020年8月9号,不得不吐槽Google。这么频繁的迭代版本,坑太多!!!)

各版本详见: 库 > 版本说明">Jetpack > 库 > 版本说明

1.2、添加到项目

WorkManager并非Frameworks库,需要额外引入到项目才能使用。但是它却能一直向后兼容到API 14,因为内部其实就是根据不同的API利用AlarmManager、JobSchedule等已有的功能二次封装。

dependencies {
	    ...
	    //WorkManager API 可以轻松地调度那些必须可靠地运行的可延期异步任务。
	    implementation "androidx.work:work-runtime:2.4.0"
	    ...
	}

2、WorkManager相关类

要借助WorkManager完成后台定时任务,需要通过辅助的一些类才能完成,这些工具类和WorkManager一起方便的完成定时任务的设置和调度。

2.1、WorkerManager

WorkManager主要管理任务请求和任务队列,将WorkRequest加入任务队列。 通过WorkManager来调度任务,以分散系统资源的负载。获取WorkManager实例:

workManager = WorkManager.getInstance(context);

看样子是单例,源码就不在这里跟踪了。

2.2、Worker

Worker是抽象类,只有留了一个抽象方法doWork(),从方法名就能看出是留给开发者实现该方法定义后台任务具体执行的代码。Google的风格总是这样,比如IntentService一样留了一个onHandleIntent(Intent intent)抽象方法给开发者去实现自己的功能。

public class SneakWork extends Worker {
        public SneakWork(Context context,WorkerParameters workerParams) {
            super(context, workerParams);
        }
    
        @Override
        public Result doWork() {
            //在这里实现后台需要执行的任务代码
            return Result.success();
        }
    }

2.3、ListenableWorker.Result

Result类是Worker后台任务执行完之后的返回结果,Result类提供了三类五个方法:

①failure()、failure(Data outputData):任务失败,可携带失败结果,应当使用简单的基本类型或者不超过10kb的Data对象。

②retry():失败并需要重试,由WorkManager自行决定何时重试该任务或者根据Request中的设置来尝试。

③success()、success(Data outputData):任务成功,携带信息。

2.4、WorkerRequest

请求任务。WorkRequest是抽象类,有两个子类OneTimeWorkRequest和 PeriodicWorkRequest,分别用来设置一次性任务和重复执行的任务。通过内部Builder类构造参数需要传入自定义的Work类class创建任务请求对象实例。

OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(HeavyWork.class)
                                                                  .build();

可以给任务请求设置各种条件,参输入数,时间,约束等。详细方法参考OneTimeWorkRequest.Builder和PeriodicWorkRequest.Builder的API

OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(HeavyWork.class)
            .setInitialDelay(3, TimeUnit.SECONDS)
            .addTag("test")
            .setConstraints(constraints)
            .build();

2.5、Constraints

Constraints类给PeriodicWorkRequest任务添加约束条件,比如在充电状态下,有网络状态下才能执行任务等等。Google提供的这个类非常贴心,替开发者考虑各种场景。通过内部的Buidler创建约束对象,再将其通过WorkRequest.Builder的setConstraints(constraints)方法给任务请求添加约束。

Constraints constraints = new Constraints.Builder()
            .setRequiresCharging(true)    //充电状态
            .setRequiresDeviceIdle(false)    //设备空闲时运行任务
            .setRequiredNetworkType(NetworkType.CONNECTED)    //需要有网络连接
            .setTriggerContentMaxDelay(5, TimeUnit.SECONDS)    //计划更改运行的最大延迟
            .build();

设置各种条件方法详见Constraints API:Docs>Reference>Constraints.Builder">Android 开发者>Docs>Reference>Constraints.Builder

        

2.6、WorkInfo

任务状态信息。WorkManager把任务添加到队列后,会给每一个WorkRequest添加一个LiveData,包含任务的状态和信息。LiveData中有WorkInfo对象,利用每个方法的 LiveData 变量,可以通过注册监听器来观察 WorkInfo 的变化。例如,如果您想要在某项工作成功完成后向用户显示消息。

3、WorkManager添加/取消任务

前面的辅助工作都做好了,创建好WorkRequest对象,如何添加到WorkManager中?又如何取消任务呢?

3.1、添加任务

创建好的WorkRequest对象,直接进入交给WorkManager队列。

workManager.enqueue(oneTimeWorkRequest);

3.2、取消任务

①通过每个WorkRequest的UUID取消特定的任务请求

UUID uuid = oneTimeWorkRequest.getId();
    workManager.cancelWorkById(uuid);

②通过给WorkRequest设置定tag取消一组相同tag的任务请求

workManager.cancelAllWorkByTag("tag");

4、任务链

WorkManager最出彩的地方在于任务链,多个任务之间可能有前后顺序关系,需要先后或者并发执行完成后,才能继续。

4.1、顺序链式

任务一个接着一个执行

/**
     *      A       
     *      |       
     *      B       
     *      |       
     *      C
     *      |    
     *      D   
     */
    workManager.beginWith(A)
            .then(B)
            .then(C)
            .then(D)
            .enqueue();

4.2、组合链式

有些任务可以并发执行,但是有些任务组间又需要有先后顺序。通过WorkContinuation类完成任务链的组合。

/**
     *      A       C
     *      |       |
     *      B       D
     *      |       |
     *      +-------+
     *          |
     *          E  
     */
    WorkContinuation AB= workManager.beginWith(A).then(B);
    WorkContinuation CD= workManager.beginWith(C).then(D);

    //先组合成一组并发任务链
    List<WorkContinuation> list = new ArrayList<>();
    list.add(AB);
    list.add(CD);
    
    //交付执行
    WorkContinuation.combine(list).enqueue();

参考资料:

         文档 > WorkManager 使用入门">Android 开发者 > 文档 > WorkManager 使用入门

         文档 > WorkManager 中的线程处理">Android 开发者 > 文档 > WorkManager 中的线程处理

         文档 > WorkManager API">Android 开发者 > 文档 > WorkManager API

        APP保活的福音?WorkManager初探

        Android Jetpack WorkManager">Bilibili > Android Jetpack WorkManager

        WorkManager 简述

        GitHub > android/architecture-components-samples

相关推荐

精选
ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager
Android

ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager

ViewPager1、ViewPagerandroidx.viewpager.widget.ViewPager,Android中使用非常广泛的控件,可以说是APP必备:首次打开引导页、页面Banner广告等。常用方法:setAdapter() 设置适配器setOffscreenPageLimit() 设置缓存的页面个数,默认是 1setCurrentItem() 跳转到特定的页面setOnPage

1.1k
获取Android内置WebView内核版本
Android

获取Android内置WebView内核版本

获取Android内置WebView内核版本竟然能遇到这样奇葩的事情,网页用的技术过于新颖,以至于只支持高版本Chromium内核的,低版本安卓系统中内置的内核版本较低,无法加载前端页面。1、设置查看在系统设置里 > 应用 > 应用管理 > 显示系统应用,查看WebView组件:2、页面查看通过WebView发起的网络请求,都会带上浏览器的UA,通常页面都可以通过UA判断浏览器的内核版本。这里有两

1.1w
Android 14适配总结
Android

Android 14适配总结

Android 14适配总结毕业工作至今已经适配了三个Android大版本,从Android 11到Android 12、再到Android 13。2023年,Google即将推出的Android 14,上半年已经开始第一批适配。现在,第四个Android版本已经适配完,总结记录一下。1、Android 14计划Google一般会在2月份对外发布预告,同时放出开发者预览版。“拉通”各大平台、厂商以

1.1w