Android(安卓)Jetpack 系列篇(二) WorkManager
本篇文章介绍 Jetpack 架构组件中的 WorkManager, 该组件可以灵活管理 Android 后台任务
主要特点
- 向后兼容API 14,在API 23+的设备上使用JobScheduler,在具有API 14-22的设备上使用BroadcastReceiver + AlarmManager的组合
- 可以设置网络状态或计费状态等约束条件
- 实现异步一次性或定期任务
- 有效监控和管理计划任务
- 实现多个任务并行或串行执行
- 应用程序或设备重新启动也可确保任务执行
- 保持Doze模式等省电功能
- 可以将日志或分析发送到后端服务
- 可以定期将应用程序数据与服务器同步
组成部分
主要由这几部分组成:Worker、WorkRequest、Constraints、WorkManager、WorkContinuation
Worker 一个任务处理的对象,专注于处理后台耗时操作,并且可以灵活接收参数和返回结果
也是一个抽象类,有一个抽象方法doWork()
,所有逻辑耗时操作都可以在这个方法里执行,如果执行成功可以返回Result.success()
, 失败返回Result.failure()
, 重试返回Result.retry()
,返回结果时可以在成功或失败中传递,如:Result.success(data)
。
WorkRequest 任务请求对象
同样是一个抽象类,系统给我们提供了两个实现类,OneTimeWorkRequest
和PeriodicWorkRequest
, 前者是一次任务,后者为循环任务。可以安排要执行的任务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
更多相关文章
- 深入理解 Android(安卓)的 IPC 机制--------Binder
- Android.jar文件分析
- Android(安卓)Graphic : apk and Skia/OpenGL|ES
- 开发必读:如何成为一名优秀的Android开发者
- Android系统的过滤机制大揭秘——原创
- UI线程处理Handle
- android 知识点汇总 这一篇就够了
- Android(安卓)中设计模式
- Android电话系统之RIL-Java