[英]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.