安卓组件开发学习——WorkManager后台任务的使用

2,157 阅读5分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 20 天,点击查看活动详情

前言

今天就想看看Jetpack,不想看Material,所以我们看看WorkManager组件的使用方法。

正文

首先我们先把WorkManager组件所需的依赖添加好,在app/build.gradle文件中添加下面依赖:

dependencies {

    ...
    implementation 'androidx.work:work-runtime:2.8.0'
   ...
}

然后我们sync gradle,在同步等待的时候,我们先了解一下WorkManager组件是干嘛的。

WorkManager概述

WorkManager首先是用来处理后台任务的,安卓的后台权限现在越来越紧,我们之前的安卓版本也有许多处理后台任务的都不能很好的兼容,总之现在后台任务没那么厉害了,限制很多,开发者要自己去选择组件兼容太麻烦。

而WorkManager组件就是Google推出的很适用于处理一些要求定时执行的任务,而且可以自动根据操作系统版本来使用相关实现方式来兼容,对我们开发者来说很友好,此外,它还能支持周期性任务处理、链式任务处理等功能,是很强大的工具。

WorkManager组件与安卓系统四大组件之一的Service不太一样,Service会在没有被销毁的情况下一直保持在后台运行,而WorkManager作为处理定时任务的工具,可以保证即使在应用推出甚至手机重启的情况下,之前注册的任务仍然可以执行,所以我们的WorkManager组件也很适合用于执行一些定期和服务器进行交互的任务,如周期性同步数据之类的。

但需要注意的是,前面也说明了,现在安卓的后台限制很大,所以WorkManager也不能保证注册的周期性任务可以准时执行,这是系统的缘故,出于省电考虑,可能几个触发时间相近的任务会放在一起执行。

WorkManager的用法

了解了WorkManager是什么后,我们来看看它的基本用法步骤:
首先,我们需要先定义一个后台任务,并且实现其具体的任务逻辑;
然后,我们配置好该任务的运行条件和约束信息,并且构建后台任务请求
最后,我们再将该后台任务的请求传入WorkManager的enqueue()方法中,这样一来,系统就会选择在合适的时间运行。

接下来,我们就开始这三个步骤,先定义一个后台任务,创建一个SimpleWorker类:

import android.content.Context
import android.util.Log
import androidx.work.Worker
import androidx.work.WorkerParameters

class SimpleWorker(context: Context, params: WorkerParameters) : Worker(context, params) {

    override fun doWork(): Result {
        Log.d("SimpleWorker", "do work in SimpleWorker")
        return Result.success()
    }

}

我们先分析一下上面的代码,这个类我们继承了Worker类,然后调用了它唯一的构造函数,接着再在类中重写了父类的doWork()方法,这个方法中我们就可以去编写具体的后台任务逻辑。完成后,我们还能看到AS的提示,我们点击Learn More后就能知道,我们可以查看APP Inspector的 WorkManager Inspector 标签页中看到活跃工作器,感觉大致应该就是可以查看我们的设备运行时WorkManager的后台工作情况,不过API要大于等于26。

image.png

image.png

言归正传,我们再细说一下都doWork()方法,它是不会运行在主线程当中的,所以我们可以在这个方法中使用耗时逻辑,而这个方法的返回要求是一个Result对象,用来表示任务的运行结果,大致有三种,用于表示成功的Result.success(),用于表示失败的Result.failure(),以及表示重试或者也是失败的Result.retry()方法,其中Result.retry()方法可以和WorkRequest.Builder的setBackoffCriteria()方法来重新执行任务。

前面我们简单的后台任务已经定义好了,我们来做第二步,也就是配置任务的运行条件和约束信息。这部分的内容其实很多,因为我们可以配置的内容是很丰富的,但本篇就提一下最基础的配置:

binding.vButton.setOnClickListener { 
    val request = OneTimeWorkRequest.Builder(SimpleWorker::class.java).build()
}

我们在Activity中加了一个按钮,我们的配置就写在这个按钮的点击事件中,首先,OneTimeWorkRequest.Builder是我们WorkRequest.Builder的子类,可以用于构建单次运行的后台任务请求,我们调用它的build()方法就完成了构建,此外,WorkRequest.Builder还有一个子类PeriodicWorkRequest.Builder,它可以构建周期性运行的后台任务请求,但为了降低设备性能消耗,它构造函数中传入的运行周期间隔不能小于十五分钟,如下:

val requestT = PeriodicWorkRequest.Builder(SimpleWorker::class.java, 15, 
TimeUnit.MINUTES).build()

这块我们还是用单次的后台任务构建作为示范,最后一步,接着我们的构建任务配置的代码下面,我们将后台任务请求传入WorkManager的enqueue()方法:

WorkManager.getInstance(applicationContext).enqueue(request)

这样就完成了我们WorkManager的基本用法。

运行后我们查看效果,其实就是我们点击一下按钮,立即就看到日志窗口的日志,因为我们没有加任何约束,所以正常就立即运行了:

image.png

总结

这里就是我们WorkManager的简单使用,后面在本文中还会更新上我们的Result.retry()方法的使用和一些时间方面的约束。