本篇文章介绍 Jetpack 架构组件中的 WorkManager, 该组件可以灵活管理 Android 后台任务

主要特点

  1. 向后兼容API 14,在API 23+的设备上使用JobScheduler,在具有API 14-22的设备上使用BroadcastReceiver + AlarmManager的组合
  2. 可以设置网络状态或计费状态等约束条件
  3. 实现异步一次性或定期任务
  4. 有效监控和管理计划任务
  5. 实现多个任务并行或串行执行
  6. 应用程序或设备重新启动也可确保任务执行
  7. 保持Doze模式等省电功能
  8. 可以将日志或分析发送到后端服务
  9. 可以定期将应用程序数据与服务器同步

组成部分

主要由这几部分组成:Worker、WorkRequest、Constraints、WorkManager、WorkContinuation

Worker 一个任务处理的对象,专注于处理后台耗时操作,并且可以灵活接收参数和返回结果

也是一个抽象类,有一个抽象方法doWork(),所有逻辑耗时操作都可以在这个方法里执行,如果执行成功可以返回Result.success(), 失败返回Result.failure(), 重试返回Result.retry(),返回结果时可以在成功或失败中传递,如:Result.success(data)

WorkRequest 任务请求对象

同样是一个抽象类,系统给我们提供了两个实现类,OneTimeWorkRequestPeriodicWorkRequest, 前者是一次任务,后者为循环任务。可以安排要执行的任务Builder()、设置执行条件setConstraints()、传递任务需要的参数setInputData()

Constraints 任务执行条件对象

设置网络状态setRequiredNetworkType()
设置电量低是否执行setRequiresBatteryNotLow()
设置充电时是否执行setRequiresCharging()
设置存储容量不足是否执行setRequiresStorageNotLow()

WorkManager 任务管理对象,通过该对象可以对任务进行预开始、监听、取消等操作

预开始任务操作beginWith()
获取任务LiveData对象getWorkInfoByIdLiveData()
取消操作cancelWorkById()

WorkContinuation 任务的延续对象,通过该对象可以对任务组合执行

连接任务操作then()
并行连接操作combine()
执行操作enqueue()

简单使用

创建一个CompressWorker, 只打印了一句话,然后返回成功

class CompressWorker(context : Context, params : WorkerParameters): Worker(context, params) {    override fun doWork(): Result {        Logger.d("doWork....")        // Indicate success or failure with your return value:        return Result.success()    }}

指定任务执行条件

val constraints = Constraints.Builder()        .setRequiredNetworkType(NetworkType.CONNECTED)  // 网络状态        .setRequiresBatteryNotLow(true)                 // 不在电量不足时执行        .setRequiresCharging(true)                      // 在充电时执行        .setRequiresStorageNotLow(true)                 // 不在存储容量不足时执行        .setRequiresDeviceIdle(true)                    // 在待机状态下执行,需要 API 23        .build()

创建任务

// 一次任务 设置条件val workA = OneTimeWorkRequest.Builder(CompressWorker::class.java).setConstraints(constraints).build()// 一次任务 传递参数val workB = OneTimeWorkRequest.Builder(MathWorker::class.java)                .setInputData(Data.Builder()                        .putInt(MathWorker.KEY_X_ARG, 1)                        .putInt(MathWorker.KEY_Y_ARG, 2)                        .putInt(MathWorker.KEY_Z_ARG, 3)                        .build())                .build()// 多次任务 间隔30分钟执行一次, 最小限制为15分钟,和 JobScheduler API 限制一样val workC = PeriodicWorkRequest.Builder(CompressWorker::class.java, 30, TimeUnit.MINUTES).build()

MathWorker

class MathWorker(context : Context, params : WorkerParameters) : Worker(context, params) {    companion object {        // Define the parameter keys:        const val KEY_X_ARG = "X"        const val KEY_Y_ARG = "Y"        const val KEY_Z_ARG = "Z"        // ...and the result key:        const val KEY_RESULT = "result"    }    override fun doWork(): Result {        val x = inputData.getInt(KEY_X_ARG, 0)        val y = inputData.getInt(KEY_Y_ARG, 0)        val z = inputData.getInt(KEY_Z_ARG, 0)        // ...do the math...        val result = myCrazyMathFunction(x, y, z)        //...set the output, and we're done!        val output: Data = Data.Builder().putInt(KEY_RESULT, result).build()        return Result.success(output)    }    private fun myCrazyMathFunction(x: Int, y: Int, z: Int): Int{        return x + y + z    }}

监听任务

WorkManager.getInstance().getWorkInfoByIdLiveData(workA.id)        .observe({ lifecycle }, { workInfo ->            // Do something with the status            if (workInfo != null && workInfo.state.isFinished) {                Logger.d("workA")            }        })WorkManager.getInstance().getWorkInfoByIdLiveData(workB.id)        .observe({ lifecycle }, { workInfo ->            // Do something with the status            if (workInfo != null && workInfo.state.isFinished) {                //获取 MathWorker 返回的数据                Logger.d("workE="+workInfo.outputData.keyValueMap[MathWorker.KEY_RESULT])            }        })WorkManager.getInstance().getWorkInfoByIdLiveData(workC.id)        .observe({ lifecycle }, { workInfo ->            // Do something with the status            Logger.d("workInfo="+workInfo?.state)            if (workInfo != null && workInfo.state.isFinished) {                Logger.d("workInfo="+workInfo.id)            }        })

执行任务

//单个任务执行WorkManager.getInstance().enqueue(workA)//多个任务串行WorkManager.getInstance().beginWith(workA).then(workB).enqueue()//workA和workB并行执行后,再执行workCWorkManager.getInstance().beginWith(listOf(workA, workB)).then(workC).enqueue()//workA和workB串行,workC和workD串行,chain1和chain2并行val chain1 = WorkManager.getInstance().beginWith(workA).then(workB)val chain2 = WorkManager.getInstance().beginWith(workC).then(workD)WorkContinuation.combine(listOf(chain1, chain2)).enqueue()

取消任务

WorkManager.getInstance().cancelWorkById(workA.id)

WorkManger 介绍就到这里了,更多详细信息,可以查看官方文档: https://developer.android.com/topic/libraries/architecture/workmanager

更多相关文章

  1. 深入理解 Android(安卓)的 IPC 机制--------Binder
  2. Android.jar文件分析
  3. Android(安卓)Graphic : apk and Skia/OpenGL|ES
  4. 开发必读:如何成为一名优秀的Android开发者
  5. Android系统的过滤机制大揭秘——原创
  6. UI线程处理Handle
  7. android 知识点汇总 这一篇就够了
  8. Android(安卓)中设计模式
  9. Android电话系统之RIL-Java

随机推荐

  1. Android(安卓)Studio一些控件的使用
  2. Android(安卓)Intent 大全
  3. android image 压缩和解压
  4. Android开发之文件下载
  5. Android(安卓)数据操作之SQLiteDatabase
  6. Android(安卓)Develop Tips
  7. Android(安卓)build.prop生成过程
  8. Android——Pull方式解析XML数据
  9. Android(安卓)官方示例:android-architect
  10. Android之四大组件