这个问题已经以不同的形式被问了很多次,但我没有得到正确的答案,并且想知道这是否可能不是一个 android bug。
设置 WorkManager 后,会随机调用 doWork(),有时会快速连续调用多达 10 次以上。
预期行为是每 10-15 分钟调用一次
详情请参阅以下: 使用 Android studio Bumblebee 2021.1.1 Patch 2 在 LG K22 上实现
渐变实现:
implementation 'androidx.work:work-runtime-ktx:2.7.1'
主要活动代码:
WorkManager.getInstance(this).cancelAllWorkByTag("scanDevices")
val myMonitorWorkerRequest = PeriodicWorkRequest.Builder(myMonitorWorker::class.java,
15, TimeUnit.MINUTES,5, TimeUnit.MINUTES).build()
WorkManager.getInstance(this)
.enqueueUniquePeriodicWork(
"scanDevices",
ExistingPeriodicWorkPolicy.KEEP,
myMonitorWorkerRequest)
原工人阶级:
override fun doWork(): Result {
try{
runNotificationService()
return Result.success()
}
catch (e:Exception){
return Result.failure()
}
}
当前工人阶级:
override fun doWork(): Result {
try{
val timeNow = System.currentTimeMillis()
if(timeNow < lastTime+600000){
WorkManager.getInstance(theContext).cancelAllWorkByTag("scanDevices")
val myMonitorWorkerRequest = PeriodicWorkRequest.Builder(myMonitorWorker::class.java,
15, TimeUnit.MINUTES,5, TimeUnit.MINUTES).build()
WorkManager.getInstance(theContext)
.enqueueUniquePeriodicWork(
"scanDevices",
ExistingPeriodicWorkPolicy.KEEP,
myMonitorWorkerRequest)
}
else{
runNotificationService()
lastTime = timeNow
}
return Result.success()
}
catch (e:Exception){
return Result.failure()
}
}
上面的代码还不是万无一失的,因为有时会如此快速地连续调用工作类,以至于同时启动多个(实例/线程(我认为)),并且全局变量的更新之前尚未生效到另一个实例启动。它确实极大地减少了调用数量,尽管只有一两个额外的实例被忽略。
具体来说,我的问题是,有谁知道我所做的事情是否错误,或者是否存在正在创建的多个工作实例/线程的已知错误报告?
请参阅我尝试过但没有成功的类似参考资料:
WorkManager 一次执行 enqueueUniquePeriodicWork() 多次?
WorkManager 的 doWork() 为 OneTimeWorkRequest 多次调用
*App Inspection 显示有 20 个实例在 android studio 上排队
我不知道具体原因,但我今天遇到了同样的问题,非常令人沮丧。所以我决定卸载该应用程序,它神奇地工作了。 希望您也是如此
我可能来得有点晚了,但对于仍然面临这个问题的人来说,这对我有用。我意识到,当使用 ExistingPeriodicWorkPolicy.UPDATE / ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE (REPLACE 现已弃用)或 enqueueUniquePeriodicWork 将工作添加到队列时,并不能帮助避免相同的工作多次入队。因此,我必须首先检查它是否与我为其设置的标签一起工作之前存在。
这是对我有用的代码(Kotlin):
WorkManager workManager = WorkManager.getInstance(this)
val tagSF: String = "SincronizacionSF"
val sfWorkInfo = workManager.getWorkInfosByTag(tagSF).get()
if (sfWorkInfo.isEmpty()) {
val periodicWorkRequest = PeriodicWorkRequestBuilder<SincronizacionSF>(15, TimeUnit.MINUTES, 0, TimeUnit.MINUTES).addTag(tagSF).build()
workManager.enqueueUniquePeriodicWork(tagSF, ExistingPeriodicWorkPolicy.UPDATE, periodicWorkRequest)
}
这适用于PeriodicWorkRequestBuilder 和OneTimeWorkRequestBuilder。
另外,要添加一个注释。一旦我添加了这段代码,我必须先删除该应用程序并再次安装它,以便队列完全清空,然后它就可以正常工作了。