Jetpack系列之WorkManager(三)

169 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情

前言

上一篇我们了解了关于workmanager基本的信息,这一篇我们着重了解一下Worker。

概览

Worker是在WorkManager提供的后台线程上同步执行工作的类。继承于ListenableWorkerWorker类在运行时是通过WorkManager实例化,doWork()方法在预先指定的后台线程上调用,这个方法用于同步处理你的工作,一旦该方法返回,工作就被认为已经完成并将被销毁。

基本使用

// work类
class MyWorker : Worker() {
    override fun doWork(): Worker.WorkerResult {
        //这里执行work工作
        ...
        // 这里提供三个返回
        // a. WorkerResult.SUCCESS  工作执行成功
        // b. WorkerResult.FAILURE  工作执行失败
        // c. WorkerResult.RETRY    工作执行重试
        return Worker.WorkerResult.SUCCESS 
    }
}

API使用

getInputData

Worker中获取外部WorkRequestsetInputDataapi所传递的数据,传递的数据类型只支持基本数据类型及其数组以及序列化数据,和Bundle传递的数据类似。

// work类
class MyWorker : Worker() {
    override fun doWork(): Worker.WorkerResult {
        // 获取数据
         val inputData = inputData.getString("INPUT_DATA")
        return Worker.WorkerResult.SUCCESS 
    }
}

setProgressAsync

Worker中可以通过setProgressAsync()来设置进度和数据。setProgressAsync()是一个异步操作方法,会调用ProgressUpdaterupdateProgress()操作数据库。只有WorkInfo的状态为RUNNING时才可以获取到setProgressAsync()设置的进度数据。

// work类
class MyWorker : Worker() {
    override fun doWork(): Worker.WorkerResult {
        // 模拟1000后进度更新
        setProgressAsync(workDataOf(Pair("key", 0)))
        Thread.sleep(1000)
        setProgressAsync(workDataOf(Pair("key", 100)))
        return Worker.WorkerResult.SUCCESS 
    }
}

// 观察进度
WorkManager.getInstance(this).getWorkInfoByIdLiveData(myWorkId).observe(lifecycleOwner, workStatus -> {
    if (null != workStatus && workStatus.state == WorkInfo.State.RUNNING) {
        // 获取进度数据
        val progress = workStatus.progress
        val value = progress.getString("key")
    }
})

setForegroundAsync

Worker中可以通过setForegroundAsync()来指定当前工作需要长时间运行,请求加入前台任务,尽可能的让系统保证进程的活动状态。需要注意的是调用setForegroundAsync必须在ListenableWorker返回ListenableWorker. result信号完成之前完成。 在底层,WorkManager管理并运行一个前台服务来代表你执行这个WorkRequest,并在ForegroundInfo中显示提供的通知。

// work类
class MyWorker : Worker() {
    override fun doWork(): Worker.WorkerResult {
        // 设置前台任务
        setForegroundAsync(createForegroundInfo())
        // 调用`setForegroundAsync`必须在`ListenableWorker`返回`ListenableWorker. result`信号完成之前完成
        return Worker.WorkerResult.SUCCESS 
    }
    
    private fun createForegroundInfo(): ForegroundInfo {

        val notificationCompat =
            NotificationCompat.Builder(applicationContext, "channelId").setContentTitle("标题")
                .setSmallIcon(R.drawable.icon_odd_close)
                .setOngoing(true)//是否为持续通知
                .build()

        return ForegroundInfo(123,notificationCompat)
    }
}