我正在创建一个备份应用程序,可以在晚上备份一些文件。因为它需要每天晚上大约在同一时间,所以我使用 OneTimeWorkRequest ,它将在上次运行后再次安排。这就是我正在使用的代码:
private fun scheduleNextSyncWorker(context: Context) {
val nextScheduleDelay = 60000L
val test = OneTimeWorkRequestBuilder<TestWorker>()
.setInitialDelay(nextScheduleDelay, TimeUnit.MILLISECONDS)
.setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.UNMETERED)
.build()
)
.addTag("test")
.build()
WorkManager.getInstance(context)
.enqueueUniqueWork("test", ExistingWorkPolicy.REPLACE, test)
}
class TestWorker(appContext: Context, workerParameters: WorkerParameters) : CoroutineWorker(appContext, workerParameters) {
override suspend fun doWork(): Result {
try {
withContext(Dispatchers.IO) {
val connectivityManager = applicationContext.connectivityManager()
var waitedMillis = 0L
var waitedSince = System.currentTimeMillis()
// Added this to check if it is connected and usually this is false
while(connectivityManager.activeNetworkInfo?.isConnected != true && waitedMillis < 10000) {
Log.d("TEST", "connected: ${connectivityManager.activeNetworkInfo?.isConnected}")
waitedMillis = System.currentTimeMillis() - waitedSince
delay(1000)
}
// Api calls here which mostly fail because no internet connection
}
return Result.success()
} catch (t: Throwable) {
return Result.failure()
} finally {
GlobalScope.launch {
// Probably not the best way, but the worker needs to pass back that we succeeded or failed before we will schedule the next
delay(1000)
scheduleNextSyncWorker(applicationContext)
}
}
}
}
当应用程序位于前台时,此代码将正常运行。然而,一旦我将应用程序移至后台并锁定设备,大多数 api 调用都会失败并显示
java.net.UnknownHostException: Unable to resolve host "graph.microsoft.com": No address associated with hostname
。
就像您在代码中看到的那样,我有一些额外的代码来检查我们当前是否已连接,当设备锁定时,这些代码大多是错误的。有时几秒钟后我们就可以重新访问互联网,但有时却不能。
我认为只有满足约束条件时 WorkManager 才应该调用 doWork 。但由于我没有有效的连接,我不确定应该如何继续。在工作线程内部添加完整的网络检查似乎很简单,而它本身应该进行检查。
有什么想法吗?
经过一番头痛和工作数小时后,我终于弄清楚了。这是新2.10.0版本中的一个bug。这是我第一次使用WorkManager,所以不知道这是否与新版本有关。只要恢复到 2.9.1 就可以再次使用了。
我在 IssueTracker 上创建了一个问题:https://issuetracker.google.com/issues/387656869