WorkManger学习汇总

一.使用

WorkManger主要是用来执行一定会执行的任务的,如即使app被杀掉、手机重启都会执行。

适用场景:定期重复性任务,如定期log上传等

使用的话首先引入库(我使用的是2.7.1)

Kotlin 复制代码
    implementation "androidx.work:work-runtime-ktx:2.7.1"

其次写个类继承Worker,重新doWork方法用来执行你的具体任务

Kotlin 复制代码
class TokenWorker(appContext: Context, workerParams: WorkerParameters) :
    CoroutineWorker(appContext, workerParams) {

    override suspend fun doWork(): Result = withContext(Dispatchers.IO) {
        try {
    
        } catch (e: Exception) {
            Result.failure()
        }
    }

}

然后在需要使用的地方,代码初始化workmanger并选用需要的方式开启任务

Kotlin 复制代码
    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()方法的原因

相关推荐
长亭外的少年2 小时前
Kotlin 编译失败问题及解决方案:从守护进程到 Gradle 配置
android·开发语言·kotlin
建群新人小猿5 小时前
会员等级经验问题
android·开发语言·前端·javascript·php
1024小神6 小时前
tauri2.0版本开发苹果ios和安卓android应用,环境搭建和最后编译为apk
android·ios·tauri
兰琛6 小时前
20241121 android中树结构列表(使用recyclerView实现)
android·gitee
Y多了个想法7 小时前
RK3568 android11 适配敦泰触摸屏 FocalTech-ft5526
android·rk3568·触摸屏·tp·敦泰·focaltech·ft5526
NotesChapter8 小时前
Android吸顶效果,并有着ViewPager左右切换
android
_祝你今天愉快9 小时前
分析android :The binary version of its metadata is 1.8.0, expected version is 1.5.
android
暮志未晚Webgl9 小时前
109. UE5 GAS RPG 实现检查点的存档功能
android·java·ue5
麦田里的守望者江9 小时前
KMP 中的 expect 和 actual 声明
android·ios·kotlin
Dnelic-10 小时前
解决 Android 单元测试 No tests found for given includes:
android·junit·单元测试·问题记录·自学笔记