开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情
WorkManager 引入 官方库
dependencies {
def work_version = "2.7.1"
// (Java only)
implementation "androidx.work:work-runtime:$work_version"
// Kotlin + coroutines
implementation "androidx.work:work-runtime-ktx:$work_version"
// optional - RxJava2 support
implementation "androidx.work:work-rxjava2:$work_version"
// optional - GCMNetworkManager support
implementation "androidx.work:work-gcm:$work_version"
// optional - Test helpers
androidTestImplementation "androidx.work:work-testing:$work_version"
// optional - Multiprocess support
implementation "androidx.work:work-multiprocess:$work_version"
}
WorkManager简介
后台执行任务,Android 提供了JobSchedule,Loader,Service等,但是如果api使用不当会消耗大量电量,WorkManager应运而生。 WorkManager为不需要及时完成的任务提供了统一的解决方案,以便设备电量和用户体验达到一个平衡 工作线程通常立即执行,而WorkManager不能保证任务能立即执行
WorkManager使用
使用Work类定义任务
class MyWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
override fun doWork(): Result {
val name = inputData.getString("name")
Log.v("zx", "doWork回调了。。$name")
//任务执行完后返回结果
val data = Data.Builder()
.putString("wresult", "我得到$name 啦")
.build()
return Result.success(data)
}
}
使用WorkManager执行任务
将任务提交给系统: workManager.enqueue
观察任务的状态:getWorkInfoByIdLiveData
取消任务:cancelWorkById
参数传递:setInputData
任务分为:单次任务和周期性任务
private fun doWorking() {
//设置触发条件
val constraints = Constraints.Builder()
//需要有网络才可以触发
//NetworkType.NOT_REQUIRED 对网络没有要求
//NetworkType.CONNECTED 网络连接时执行
//NetworkType.UNMETERED 不计费的网络,比如wifi下执行
//NetworkType.NOT_ROAMING 非漫游网络下执行
//NetworkType.METERED 计费网络下比如3g,4g下执行
//注意:不代表恢复网络后立马执行,由系统决定的
.setRequiredNetworkType(NetworkType.NOT_REQUIRED)
//不在电量不足的时候执行
//.setRequiresBatteryNotLow(true)
//在充电时执行
//.setRequiresCharging(true)
//不在存储容量不足时执行
//.setRequiresStorageNotLow(true)
//在待机状态下执行
//最低api为23
//.setRequiresDeviceIdle(true)
.build()
val data = Data.Builder()
.putString("name", "诸葛亮")
.build()
//配置任务
//配置只执行一次的任务
//val oneTimeWorkRequest = OneTimeWorkRequest.Builder(MyWork::class.java).build()
val oneTimeWorkRequest = OneTimeWorkRequestBuilder<MyWorker>()
//设置触发条件
.setConstraints(constraints)
//设置延迟执行(延迟5秒执行)
.setInitialDelay(5, TimeUnit.SECONDS)
//指数退避策略(最低api为26)
//.setBackoffCriteria(BackoffPolicy.LINEAR, Duration.ofSeconds(2))
//设置tag标签
.addTag("onetag")
//参数传递到work中
.setInputData(data)
.build()
//周期任务的时间不能少于15分钟
val periodicWorkRequest = PeriodicWorkRequestBuilder<MyWorker>(Duration.ofMinutes(15))
.build()
//任务提交给workmanager
val workManager = WorkManager.getInstance(this)
//观察任务状态(ENQUEUED:已加入队列,SUCCEEDED:执行成功)
workManager.getWorkInfoByIdLiveData(oneTimeWorkRequest.id).observe(this, Observer {
Log.v("zx", "onetime是:$it.toString()")
if (it != null && it.state == WorkInfo.State.SUCCEEDED) {
val wResult = it.outputData.getString("wresult")
Log.v("zx", "观察执行结果:$wResult")
}
})
workManager.enqueue(oneTimeWorkRequest)
//取消任务(5秒后执行,我们在2秒后就取消)
/* Timer().schedule(object : TimerTask() {
override fun run() {
Log.v("zx", "2秒后取消")
workManager.cancelWorkById(oneTimeWorkRequest.id)
}
}, 2000)*/
}
任务链(控制任务执行顺序)
哪个任务先执行,哪个任务后执行,哪些任务先执行,哪些任务后执行
简单任务链
//简单任务链
private fun doWorkChain() {
val aOneTimeWorkRequest = OneTimeWorkRequestBuilder<MyWorker>()
//设置tag标签
.addTag("atag")
.build()
val bOneTimeWorkRequest = OneTimeWorkRequestBuilder<MyWorker>()
//设置tag标签
.addTag("btag")
.build()
//任务提交给workmanager
val workManager = WorkManager.getInstance(this)
workManager
.beginWith(aOneTimeWorkRequest)
.then(bOneTimeWorkRequest)
.enqueue()
}
执行结果
Worker result SUCCESS for Work [ id=a1180046-3a4e-46eb-954f-f08dd9a5ead8, tags={ atag, com.z.zjetpack.workmanager.MyWorker } ]
Worker result SUCCESS for Work [ id=8967c3ef-18c6-4e9a-bed6-3cdaa2e62de3, tags={ btag, com.z.zjetpack.workmanager.MyWorker } ]
根据日志可以发现,先执行了atag,后执行了btag
复杂任务链
//复杂任务链,任务链组合
private fun doWorkChains() {
val aOneTimeWorkRequest = OneTimeWorkRequestBuilder<MyWorker>()
//设置tag标签
.addTag("atag")
.build()
val bOneTimeWorkRequest = OneTimeWorkRequestBuilder<MyWorker>()
//设置tag标签
.addTag("btag")
.build()
val cOneTimeWorkRequest = OneTimeWorkRequestBuilder<MyWorker>()
//设置tag标签
.addTag("ctag")
.build()
val dOneTimeWorkRequest = OneTimeWorkRequestBuilder<MyWorker>()
//设置tag标签
.addTag("dtag")
.build()
val eOneTimeWorkRequest = OneTimeWorkRequestBuilder<MyWorker>()
//设置tag标签
.addTag("etag")
.build()
//任务提交给workmanager
val workManager = WorkManager.getInstance(this)
val abWorkContinuation = workManager
.beginWith(aOneTimeWorkRequest)
.then(bOneTimeWorkRequest)
val cdWorkContinuation = workManager
.beginWith(cOneTimeWorkRequest)
.then(dOneTimeWorkRequest)
val cons = arrayListOf(abWorkContinuation, cdWorkContinuation)
WorkContinuation.combine(cons)
.then(eOneTimeWorkRequest)
.enqueue()
}
执行结果
Worker result SUCCESS for Work [ id=f70e1c39-cb4d-472d-bfbf-44339de90390, tags={ atag, com.z.zjetpack.workmanager.MyWorker } ]
Worker result SUCCESS for Work [ id=1f010a32-7f3e-42dd-94c8-db9c0d7c01b1, tags={ ctag, com.z.zjetpack.workmanager.MyWorker } ]
Worker result SUCCESS for Work [ id=9fb07869-aec1-4218-8302-09803c488978, tags={ btag, com.z.zjetpack.workmanager.MyWorker } ]
Worker result SUCCESS for Work [ id=6a1afcf3-8863-49db-aaaf-8c2b6a6d9055, tags={ dtag, com.z.zjetpack.workmanager.MyWorker } ]
Worker result SUCCESS for Work [ id=7ab975dd-3516-430b-88e2-23f11fe52c32, tags={ androidx.work.impl.workers.CombineContinuationsWorker } ]
Worker result SUCCESS for Work [ id=4fd1ad90-1bb1-4cf4-815a-92c140f5565c, tags={ etag, com.z.zjetpack.workmanager.MyWorker } ]
根据日志可以发现,先执行了atag,btag,ctag,dtag执行完后再执行的etag