WorkManager退避延迟在某些设备上不起作用

时间:2019-01-15 10:11:47

标签: android android-architecture-components android-jetpack android-workmanager

我想启动一个执行某些任务的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

此外,我还在其他几种设备上对此进行了测试:Samsung Galaxy J3-8.0,Google Pixel XL-8.1,Samsung Galaxy J1-5.1.1。在所有这些设备上都能正常工作。

WorkManager的版本为1.0.0-beta01

这种不一致的原因可能是什么?有可能修复它吗?

2 个答案:

答案 0 :(得分:1)

编辑: WorkManager 1.0.0-beta02a fix for a bug that seems related to the problem you've一起发布了

  

解决了一种极端情况,即在运行Android 6.0(API级别23)的设备上,定期工作可能每间隔运行一次以上。

原始答案:
您应该尝试避免在每次应用程序启动时使WorkRequest入队。 WorkManager会为您恢复工作,而您无需这样做。 有关WorkManager以及它可以为您做什么的更多信息,您应该看看this blog series。还有Android Developer Summit演讲"Working with 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)。

这可能是您在网络设备上获得的其他日志的来源。

答案 1 :(得分:0)

我创建了这个问题,应该在下一版WorkManager中修复:https://issuetracker.google.com/issues/122881597