在延迟的持续时间内重复任务

Hay*_*ung 5 android kotlin kotlin-coroutines

我必须在时间范围内移动进度条,例如在 6 秒内。我正在使用协程和“重复”功能。代码会执行,但总执行时间不符合规定。下面是我的代码。

val progressJob = Job()
var startTime = 0L
CoroutineScope(Dispatchers.Default + progressJob).launch {
    startTime = System.currentTimeMillis()
    repeat(1000) {
        progressBar.progress += 1
        delay(6)
    }
    Log.d(TAG, "total time= ${System.currentTimeMillis() - startTime}")
}
Run Code Online (Sandbox Code Playgroud)

我预计“总时间”将是 6000,但我得到的值大于 6000 至少 500。

基本上我只想在一个时间范围内重复增加进度条,并且由于性能问题我没有使用动画。

有什么我想念的吗?

Jav*_*tar 5

我会用这样的东西来做:

withTimeout(1300L) {
    repeat(1000) { i ->
        println("Blip Blop $i ...")
        delay(500L)
    }
}
Run Code Online (Sandbox Code Playgroud)

有关更多示例,请参阅官方文档: https ://kotlinlang.org/docs/reference/coroutines/cancellation-and-timeouts.html


Lau*_*nce 2

所以你在这里所做的就是模拟进展。理想情况下,应该有某种方法来检查栏的实际进度并更新它,并在完成后结束。但是,如果这是不可能的,那么模拟是您的选择。

因此,通过协程,我们正在处理一个线程环境,并且在其中,我们有我们的协程,当移交执行控制时需要继续执行。在您的实现中,这发生在delay调用时。因此,很难保证您的协程会在您期望的时间内完成。所有延迟所能做的就是说,在“至少”指定的时间过去之前它不会恢复,并且很可能经常会过去更多的时间,而不是确切的时间。

那么,我们如何让它在尽可能接近您期望的时间范围内执行呢?我们需要做的是删除repeat,而是检查经过的时间来决定是否完成。这是一个粗略的实现,希望能有所帮助。

class Bar(val barLength: Int = 1000) {
    var progress = 0
}

suspend fun simulateProgress(bar: Bar, job: Job, totalDurationMillis: Long, incrementsMills: Long): Job {
    var startTime = System.currentTimeMillis()
    return CoroutineScope(Dispatchers.Default + job).launch {
        var totalElapsed = 0L
        while (totalElapsed < totalDurationMillis) {
            totalElapsed = System.currentTimeMillis() - startTime
            val progressRatio = totalElapsed.toDouble()/totalDurationMillis.toDouble()
            bar.progress = (progressRatio * bar.barLength.toDouble()).toInt()
            delay(incrementsMills)
        }
        println("Elapsed: $totalElapsed, Progress: ${bar.progress}")
    }
}

fun main() = runBlocking {
    val job = Job()
    val bar = Bar()
    val progressJob = simulateProgress(bar, job, 6000, 10)
    progressJob.join()
} 
Run Code Online (Sandbox Code Playgroud)