[英]WorkManager backoff delay doesn't work on some devices
我想开始一个Worker
执行一些任务,并在发生错误的情况下,一些延迟与指数退避策略后再次尝试。
为了简洁起见,以下是简化的Worker
:
class TestWorker(
context: Context,
workerParameters: WorkerParameters
) : Worker(
context,
workerParameters
) {
override fun doWork(): Result {
Log.d("DEBUG", "Attempt $runAttemptCount")
return Result.retry()
}
}
这就是我安排这个Worker
:
class MainActivity : AppCompatActivity() {
private val TAG = "WORKER_TAG"
private val BACKOFF_DELAY_SECONDS = 60L
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val workManager = WorkManager.getInstance()
workManager.cancelAllWork()
val workRequest = OneTimeWorkRequest.Builder(TestWorker::class.java)
.setConstraints(
Constraints
.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
)
.setBackoffCriteria(
BackoffPolicy.EXPONENTIAL,
BACKOFF_DELAY_SECONDS,
TimeUnit.SECONDS
)
.addTag(TAG)
.build()
workManager.enqueue(workRequest)
}
}
它在大多数设备上都很好用,但是我观察到某些设备上的异常行为。
我希望尝试2在1分钟后执行,但是在Samsung J1 6.0.1上,我看到以下日志:
01-15 12:39:57.438 28396-28435/test.ru.workerissue D/DEBUG: Attempt 0
01-15 12:39:58.349 28396-28439/test.ru.workerissue D/DEBUG: Attempt 1
01-15 12:39:58.389 28396-28440/test.ru.workerissue D/DEBUG: Attempt 2
01-15 12:40:59.669 28396-28435/test.ru.workerissue D/DEBUG: Attempt 3
01-15 12:40:59.719 28396-28439/test.ru.workerissue D/DEBUG: Attempt 4
如您所见,除2和3之外的所有尝试之间的延迟约为1秒。
如果我在Nexus 6X 8.1上运行相同的代码,则会观察到启动时同时触发了两次尝试,然后所有操作均按预期进行:
2019-01-15 13:01:06.610 28806-28841/test.ru.workerissue D/DEBUG: Attempt 0
2019-01-15 13:01:06.658 28806-28842/test.ru.workerissue D/DEBUG: Attempt 1
2019-01-15 13:02:06.747 28806-28975/test.ru.workerissue D/DEBUG: Attempt 2
2019-01-15 13:04:06.876 28806-29024/test.ru.workerissue D/DEBUG: Attempt 3
另外,我在其他几款设备上对此进行了测试:三星Galaxy J3-8.0,Google Pixel XL-8.1,三星Galaxy J1-5.1.1。 在所有这些设备上都能正常工作。
WorkManager
的版本是1.0.0-beta01
这种不一致的原因可能是什么? 有可能修复它吗?
编辑: WorkManager 1.0.0-beta02已发布, 修复了似乎与您所遇到的问题相关的错误。
修复了一种极端情况,在这种情况下,定期运行可能在运行Android 6.0(API级别23)的设备上每个间隔运行一次以上。
原始答案:
您应该尝试避免在每次应用程序启动时使WorkRequest入队。 WorkManager会为您恢复工作,而您无需这样做。 有关WorkManager以及它可以为您做什么的更多信息,您应该看一下该博客系列 。 还有Android开发者峰会演讲“使用WorkManager”中的视频对此进行了解释。
如果您需要在每次启动应用程序时将新作品入队,建议您使用REPLACE
策略将其作为唯一工作线程入队:
private val TAG = "WORKER_TAG"
private val BACKOFF_DELAY_SECONDS = 60L
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val workManager = WorkManager.getInstance()
val workRequest = OneTimeWorkRequest.Builder(TestWorker::class.java)
.setConstraints(
Constraints
.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
)
.setBackoffCriteria(
BackoffPolicy.EXPONENTIAL,
BACKOFF_DELAY_SECONDS,
TimeUnit.SECONDS
)
.addTag(TAG)
.build()
// The first parameter is a unique string that identifies the work, I'm using the TAG here.
workManager.enqueueUniqueWork(TAG, ExistingWorkPolicy.REPLACE, workRequest)
}
}
我看到您正在使用cancelAllWork()
方法。 这是一种危险的方法,您不会采取任何措施来阻止它运行时停止工作(例如,调用isStopped
)。
这可能是您在Nexus设备上获得的其他日志的来源。
我创建了这个问题,应该在下一版本的WorkManager
修复: https : //issuetracker.google.com/issues/122881597
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.