具有 `.setRequiredNetworkType(NetworkType.UNMETERED)` 的 WorkManager 在 `doWork` 内没有活动的互联网连接

问题描述 投票:0回答:1

我正在创建一个备份应用程序,可以在晚上备份一些文件。因为它需要每天晚上大约在同一时间,所以我使用 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 。但由于我没有有效的连接,我不确定应该如何继续。在工作线程内部添加完整的网络检查似乎很简单,而它本身应该进行检查。

有什么想法吗?

android android-workmanager android-background android-connectivitymanager
1个回答
0
投票

经过一番头痛和工作数小时后,我终于弄清楚了。这是新2.10.0版本中的一个bug。这是我第一次使用WorkManager,所以不知道这是否与新版本有关。只要恢复到 2.9.1 就可以再次使用了。

我在 IssueTracker 上创建了一个问题:https://issuetracker.google.com/issues/387656869

© www.soinside.com 2019 - 2024. All rights reserved.