Android 中 Kotlin 上的计时器实现:应该使用带延迟的协程还是 CountDownTimer

lin*_*age 5 android timer kotlin kotlin-coroutines android-jetpack-compose

根据这个答案的评论,使用CountDownTimer

val timer=object:CountDownTimer(Long.MAX_VALUE,10){
            override fun onTick(p0: Long) {
                _mutableLiveData.postValue(newValue)
            }
            override fun onFinish() {
                TODO("Not yet implemented")
            }
        }.also { it.start() }
Run Code Online (Sandbox Code Playgroud)

从 a 内部ViewModel否则会导致内存泄漏。另一方面使用实现定时器viewModelScope.launch

viewModelScope.launch {
            while (true){
                _mutableLiveData.postValue(newValue)
                delay(10)
            }
}
Run Code Online (Sandbox Code Playgroud)

从内部同样ViewModel浪费资源,因为线程在执行其任务后应该退出而不是进入睡眠状态。

我应该使用哪种方式?

我还错过了其他一些惯用的方式吗?

我的问题的上下文是这样的:在 a 中ViewModel,我的计时器实现(当前使用)定期更改a中正在使用的delay私有状态。MutableLiveDataobserveAsState@Composable

Ten*_*r04 8

如果 CountDownTimer 关联的对象超出范围时不清理它,则只会泄漏内存。因此,在 ViewModel 中,您应该将对其的引用存储在属性中,并cancel()onCleared(). 在 Activity 中,您可以在 中取消它onDestroy()。等等。

viewModelScope被设置为在 ViewModel 被销毁时自动取消正在运行的任何协程,因此您不必担心泄漏。

同样,lifecycleScope在 Activity 或 Fragment 中执行相同的操作,并viewLifecycle.lifecycleScope为 Fragment 的 View 生命周期执行此操作。

调用sleep线程会阻​​止该线程执行任何工作,因此它会占用处理器的核心。并且绝对不能在主线程上完成,因为这会锁定 UI。

在协程中,delay不会锁定任何线程或协程,因此同样的问题不适用。

  • *在协程中,延迟不会锁定任何线程或协程,因此同样的问题不适用。*这清除了问题 thnx (2认同)