WorkManger学习汇总-CSDN博客
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
一.使用
WorkManger主要是用来执行一定会执行的任务的如即使app被杀掉、手机重启都会执行。
适用场景定期重复性任务如定期log上传等
使用的话首先引入库我使用的是2.7.1
implementation "androidx.work:work-runtime-ktx:2.7.1"
其次写个类继承Worker重新doWork方法用来执行你的具体任务
class TokenWorker(appContext: Context, workerParams: WorkerParameters) :
CoroutineWorker(appContext, workerParams) {
override suspend fun doWork(): Result = withContext(Dispatchers.IO) {
try {
} catch (e: Exception) {
Result.failure()
}
}
}
然后在需要使用的地方代码初始化workmanger并选用需要的方式开启任务
private val workManager: WorkManager by lazy {
WorkManager.getInstance(applicationContext)
}
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val tokenRefreshWorkRequest = PeriodicWorkRequestBuilder<TokenWorker>(50, TimeUnit.MINUTES)
.setConstraints(constraints)
.setInitialDelay(initialDelay, TimeUnit.MILLISECONDS)
.addTag(tokenRefreshWorkName)
.build()
workManager.enqueueUniquePeriodicWork(
tokenRefreshWorkName,
ExistingPeriodicWorkPolicy.REPLACE,
tokenRefreshWorkRequest
)
我这里实现的是50分钟重复一次的任务约束条件是网络连接以及app在前台的条件下
官网上也有很多使用实例可供参考学习
二.原理
1.WorkManger是在什么地方初始化的
当我们使用WorkManger时会发现在生成的apk中provider子标签下有WorkManagerInitializer这个东西这就是入口同时发现有androidx.startup。
点进去发现继承自Initializer和以前的版本不太一样了以前看说是借助ContentProvider实现的在 AndroidX Startup 之前开发者通常会使用 ContentProvider 来在应用启动时初始化库。这是因为 ContentProvider 会在所有其他组件如 Activity之前创建和初始化。然而这种方法有一些缺点例如它会增加启动时间并且使用 ContentProvider 可能会导致一些不必要的复杂性。AndroidX Startup 库提供了一种替代方案可以避免这些问题。WorkManger就是更新了实现的方式。
WorkManager.initialize(context, new Configuration.Builder().build())中就是创建的操作。最后发现实际上是WorkManagerImpl
通过WorkDatabse创建了任务列表并记录每一个任务的属性、执行条件顺序以及状态等从而确保任务遭遇不测后手机关机重启等可以恢复继续执行
一路调用下来发现真正有作用的是internalInit方法同时我们发现schedulers是GreedyScheduler
在ForceStopRunnable的run()方法中我们发现它会完成那些被意外中断的任务。
以上就是WorkManger的初始化
2.dowork()
当我们在代码中通过各种方式调用enqueue()时通过多种调用最后都会走到WorkManagerImpl的startWork方法
最后发现StartWorkRunnable中run里面调用了startWork()方法
显然getProcessor是Processor点进去继续看会发现
在runWorker()方法中我们发现startWork()
而startWork是Worker的方法并在里面执行doWork方法这就是我们要继承Worker并重写doWork方法的原因