так что вы делаете здесь, имитируя прогресс.В идеале, должен быть какой-то способ проверки фактического прогресса вашего бара, его обновления и, когда это будет сделано, окончания.Но если это невозможно, то да, симуляция - ваш выбор.
Итак, с сопрограммами мы имеем дело с многопоточным окружением, и в этом у нас есть наши сопрограммы, которые нужно продолжать, когда руканад контролем исполнения.В вашей реализации это происходит при вызове 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()
}