Jetpack架构组件 (三)-- WorkManager使用

一、WorkManager 的介绍

WorkManager 是用来执行后台任务的,例如,发送应用程序日志、同步应用程序数据、备份用户数据等。WorkManager 能保证任务一定会被执行,即使应用程序当前不在运行中,甚至在设备重启过后,任务仍然会在适当的时刻被执行。

这是因为 WorkManager 有自己的数据库,关于任务的所有信息和数据都保存在该数据库中。因此,只要任务交给了 WorkManager ,哪怕应用程序彻底退出,或者设备被重新启动,WorkManager 依然能够保证完成你交给它的任务。WorkManager 最低能兼容 API Level 14,并且不需要你的设备安装 Google Play Services。因此,不用过于担心兼容性问题,因为 API Level 14 已经能够兼容几乎 100% 的设备。

二、WorkManager 的使用

依赖如下:

implementation "androidx.work:work-runtime:2.6.0"

注意:WorkManager 需要 compileSdk 版本 28 或更高版本。

1、 创建简单的任务

这里我们先学习如何创建一次性执行的任务,首先我们需要继承 Worker 并实现 doWork() 方法,所执行的任务就在这个方法中执行,在任务中我们打印一句话,代码如下:

public class SimpleWork extends Worker {
    
    public SimpleWork(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }
​
    @NonNull
    @Override
    public Result doWork() {
        Log.d("lx-test", "简单任务,执行完毕,doWork 线程:" + Process.myTid());
        return Result.success();
    }
}

doWork()方法的返回值类型为Result,它有三种状态:

Result.success() :执行成功。

Result.failure() :执行失败。

Result.retry() :需要重新执行。

在 Activity 中执行任务的代码如下,其中 OneTimeWorkRequest 是只执行一次的任务请求继承自 WorkRequest

WorkRequest 代表一个独立的可以执行的任务,以及任务执行的条件和规则,比我说任务执行一次还是多次,以及任务的触发调试是什么,任务有什么约束等。

WorkManager 提供队列将要执行的 WorkManager 放到队列中管理和执行。

流程如下:

/**
 * 简单任务
 *
 * @param view
 */
public void simpleWork(View view) {
    Log.d("lx-test","主线程:" + Process.myTid());
    OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(SimpleWork.class)
            /**
             * 给任务添加 Tag,后面可以根据 Tag取消任务
             * 不添加会默认用 包名+SimpleWork
             */
            .addTag("task")
            .build();
    WorkManager.getInstance(this).enqueue(oneTimeWorkRequest);
​
}

执行结果如下:

通过上面的结果可以知道,doWork 方法并不是在主线程中执行的,而是在 WorkManager 管理的后台线程中执行的,因此不可以在 doWork 方法中更新 UI 。

另外我们还可以给任务添加延时执行,如下所示,通过 setInitialDelay() 方法将任务的执行延迟2秒。

/**
 * 简单任务
 *
 * @param view
 */
public void simpleWork(View view) {
    OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(SimpleWork.class)
            .setInitialDelay(2, TimeUnit.SECONDS)
            .build();
    WorkManager.getInstance(this).enqueue(oneTimeWorkRequest);
​
}

可以给任务加一些运行的 Constraints 条件,比如说当设备空闲时或者正在充电或者连接 WiFi 时执行任务。

/**
 * 简单任务
 *
 * @param view
 */
public void simpleWork(View view) {
    Constraints constraints = new Constraints.Builder()
            .setRequiresDeviceIdle(true) // 设备空闲
            .setRequiresCharging(true)   // 设备充电
            .build();
    OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(SimpleWork.class)
            .setConstraints(constraints)
            .build();
    WorkManager.getInstance(this).enqueue(oneTimeWorkRequest);
​
}

2、Worker的数据传递

数据我们使用 Data 来进行传递,Activity 中向 Worker 传递数据通过 setInputData() 方法,并且我们在这里也监听了 Worker 回传的数据,代码如下所示:

public class TransferWork extends Worker {
    public TransferWork(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }
​
    @NonNull
    @Override
    public Result doWork() {
        String inputData = getInputData().getString("data");
        Log.d("lx-test", "Work接收到的数据:" + inputData + ",doWork 线程:" + Process.myTid());
        Data data = new Data.Builder()
                .putString("data", "Worker的数据").build();
        return Result.success(data);
    }
}

在Activity中执行任务的代码如下:

    /**
     * 数据传递
     * @param view
     */
    public void transferData(View view) {
        Log.d("lx-test","主线程:" + Process.myTid());
        Data data = new Data.Builder()
                .putString("data", "Activity的数据")
                .build();
        OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(TransferWork.class)
                .setInputData(data)
                .build();
​
        WorkManager.getInstance(this).enqueue(oneTimeWorkRequest);
​
        WorkManager.getInstance(this)
                .getWorkInfoByIdLiveData(oneTimeWorkRequest.getId())
                .observe(this, new Observer<WorkInfo>() {
                    @Override
                    public void onChanged(WorkInfo workInfo) {
                        if (workInfo.getState().isFinished()) {
                            Data outputData = workInfo.getOutputData();
                            Log.d("lx-test", "WorkManger回传的数据:" + outputData.getString("data") +
                                    ", onChanged 线程:" + Process.myTid());
                        }
                    }
                });
    }
​

执行结果如下:

通过上面的结果可以知道,onChanged 方法是执行在主线程中的,可以直接更新 UI 。

3、任务链

这里我们可以使用 WorkManager 的 beginWith() 和 then() 方法设置先执行的任务和后执行的任务,beginWith() 和 then() 方法也都可以传递任务集合。

public class MultiWork extends Worker {
    public MultiWork(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }
​
    @NonNull
    @Override
    public Result doWork() {
        String inputData = getInputData().getString("data");
        Log.d("lx-test", "任务链接收到的数据:" + inputData);
        return Result.success();
    }
}

在Activity中执行任务的代码如下:

/**
 * 任务链
 * @param view
 */
public void multiWork(View view) {
    List<OneTimeWorkRequest> workRequestList = new ArrayList<>();
    OneTimeWorkRequest oneTimeWorkRequest1 = new OneTimeWorkRequest.Builder(MultiWork.class)
            .setInputData(new Data.Builder().putString("data","任务1").build())
            .build();
    OneTimeWorkRequest oneTimeWorkRequest2 = new OneTimeWorkRequest.Builder(MultiWork.class)
            .setInputData(new Data.Builder().putString("data","任务2").build())
            .build();
    OneTimeWorkRequest oneTimeWorkRequest3 = new OneTimeWorkRequest.Builder(MultiWork.class)
            .setInputData(new Data.Builder().putString("data","任务3").build())
            .build();
​
    workRequestList.add(oneTimeWorkRequest1);
    workRequestList.add(oneTimeWorkRequest2);
​
    WorkManager.getInstance(this)
            .beginWith(oneTimeWorkRequest3)
            .then(workRequestList)// 集合中的任务按照添加的先后顺序依次执行
            .enqueue();
}

4、周期性任务

前面提到过的 OneTimeWorkRequest 是一次性任务。一次性任务在任务成功执行后,便彻底结束。而周期性任务则需要通过 PeriodicWorkRequest 来实现,它会按照设定的时间定期执行。二者使用起来没有太大差别。需要注意的是,周期性任务的间隔时间不能少于15分钟,具体代码如下:

public class PeriodicWork extends Worker {
    public PeriodicWork(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }
​
    @NonNull
    @Override
    public Result doWork() {
        Log.d("lx-test","周期性任务");
        return Result.success();
    }
}

在Activity中执行任务的代码如下:

/**
 * 周期任务
 * @param view
 */
public void periodicWork(View view) {
    PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest
            .Builder(PeriodicWork.class,15,TimeUnit.MINUTES)
            .build();
    WorkManager.getInstance(this)
            .enqueue(periodicWorkRequest);
}

特别说明

  1. PeriodicWorkRequest 重复执行任务,直到被取消才停止。首次执行是任务提交后立即执行或者满足所给的 Constraints 条件。以后执行都会根据所给的时间间隔来执行。注意任务的执行可能会有延时,因为WorkManager 会根据 OS 的电量进行优化。因此如果需要准确的间隔时间来执行任务的话不能使用PeriodicWorkRequest。

  2. PeriodicWorkRequest 默认的时间间隔是15分钟如果设置的时间小于15分钟,就会出现 PeriodicWorkRequest只执行一次,并不重复执行。

5、取消任务

//根据id取消
WorkManager.getInstance(this).cancelWorkById(oneTimeWorkRequest1.getId());
//取消所有
WorkManager.getInstance(this).cancelAllWork();
//根据Tag取消
WorkManager.getInstance(this).cancelAllWorkByTag("Tag");

扫描下方二维码关注公众号,获取更多技术干货。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Jetpack是一套基于Android开发语言Kotlin的组件库,目的是帮助Android开发者快速构建健壮的、高效的应用程序。Jetpack架构组件从入门到精通是一本介绍Jetpack组件库的电子书,其内容向读者提供了Jetpack组件库的最基础的知识体系,以及对组件库的更高阶的实践知识和技能分享。 在读者学习这本电子书时,首先会学习到基本的Jetpack概念,并了解到如何使用各种工具来实现底层代码、布局和资源文件的编写。同时,电子书重点讲解了Jetpack组件库中最常用的组件,比如ViewModel、LiveData、Room、WorkManager等,它们各自的功能和用法,让读者熟知Jetpack组件的基本运作原理。读者还会学习如何将这些组件综合使用,以构造真正的应用程序。在内容的后半部分,电子书重点讲解了Jetpack架构层面的设计,以及如何更有效的使用和管理组件库。 总之,Jetpack架构组件从入门到精通这本电子书非常适合想要学习Jetpack组件库的Android初学者和有一定开发经验的开发者,能够帮助他们快速掌握Jetpack组件库,以及提高软件的可扩展性和有效性。 ### 回答2: Jetpack架构组件是一组Android软件组件和库,通过这些组件和库,开发者可以更加轻松地开发应用程序,并提供高质量的用户体验。Jetpack架构组件包括众多不同的组件和库,这些组件和库都具有不同的用途和功能。对于开发者来说,学习Jetpack架构组件是非常重要的。 《jetpack架构组件从入门到精通 pdf》是一份针对Jetpack架构组件的学习资料。它是可以帮助开发者更好地理解和掌握Jetpack架构组件的重要手册。通过这份PDF文档,开发者可以学习到Jetpack架构组件的基本概念、用途和功能,并了解如何将这些组件和库应用到他们的应用程序开发中。 这份PDF文档涵盖了Jetpack架构组件的多个方面,包括ViewModel、LiveData、Data Binding、Room、Navigation、WorkManager等等。每个章节都包含了详细的介绍和具体的用例,从而帮助开发者更好地理解每个组件和库的用途和功能。 无论是初学者还是经验丰富的开发者,都可以从这份PDF文档中获益。它可以帮助初学者更轻松地入门Jetpack架构组件,并提供了有用的工具和技巧。对于经验丰富的开发者来说,这份PDF文档可以帮助他们更深入地了解Jetpack架构组件,并提供了一些高级技术和策略,以优化应用程序性能和用户体验。 总之,Jetpack架构组件从入门到精通的PDF文档是一份非常有价值的资源,它可以帮助开发者更好地理解和掌握Jetpack架构组件,从而更加轻松地开发高质量的Android应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值