Kotlin coroutines.delay 在后台花费太多时间

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

我有一个带有 kotlin 的 Android 应用程序,其中我需要每 X 秒执行一次 http 请求(以 10 秒为例),问题是在执行请求后我希望手机等待这 10 秒。但只有当手机处于后台且屏幕关闭时才会发生这种情况。

我创建了一个简单的示例来显示该问题,我删除了任何http请求,这里我只使用延迟并写入一些日志

在 MainActivity 的 onCreate 方法上,我调用此函数:

    private fun executeCoroutineScope() {
       CoroutineScope(Dispatchers.IO).launch(Dispatchers.IO) {
            while (isActive) {
                val sleepTime = System.currentTimeMillis()
                delay(10000)
                val sleptTime = System.currentTimeMillis() - sleepTime
                if (sleptTime > 11000) {
                    Log.w("Waking up", "After ${sleptTime / 1000}s")
                } else {
                    Log.v("Waking up", "After ${sleptTime / 1000}s")
                }
            }
        }
    }

当手机屏幕打开时,我看到睡眠时间总是只比 10 秒高几毫秒,所以我写了详细日志。但是,当屏幕关闭时,延迟(10000)有时需要几分钟才能完成,正如我们在日志中看到的那样 here

前 2-3 条日志是在屏幕打开的情况下进行的,当我将其关闭时,我们可以看到 sleepTime 如何发生一些重大变化,从 33 秒到甚至 4 分钟半。

我尝试使用

GlobalScope.launch(Dispatchers.IO)
和lifecycleScope.launch而不是
CoroutineScope(Dispatchers.IO).launch(Dispatchers.IO)
,但结果是相同的。我还尝试使用 Thread.sleep 而不是延迟,但性能也没有变化

我还停用了电池优化,所以这不应该是问题,知道如何解决它吗? (如果可以的话)

kotlin background delay
1个回答
0
投票

OEM 电池保护程序可能会导致这种情况。

我已在 Samsung SM-T387W、Android 10 上确认 - 启用 OEM 省电模式会导致这种情况发生。禁用 OEM 电池保护程序可以停止过度睡眠。我不相信可以通过我们的应用程序访问这些内容。

为了解决这个问题,我在 startForeground() 时在服务中获取了 WAKE LOCK,并在 stopForeground() 时释放它。

https://developer.android.com/training/scheduling/wakelock

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