viewModelScope未取消

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

观看Sean's explanation on Android (Google I/O'19)后,我尝试了相同的方法:

init{
    viewModelScope.launch {
        Timber.i("coroutine awake")
        while (true){
            delay(2_000)
            Timber.i("another round trip")
        }
    }
}

[不幸的是,onCleared是在活动被杀死时调用的,但当它置于后台时才被调用(“当我们离开Activity ...时,背景正在“移开” imho ^^)。我得到以下输出:

> ---- Activity in Foreground
> 12:41:10.195  TEST: coroutine awake
> 12:41:12.215  TEST: another round trip
> 12:41:14.231  TEST: another round trip
> 12:41:16.245  TEST: another round trip
> 12:41:18.259  TEST: another round trip
> 12:41:20.270  TEST: another round trip
> ----- Activity in Background (on onCleared not fired)
> 12:41:22.283  TEST: another round trip
> 12:41:24.303  TEST: another round trip
> 12:41:26.320  TEST: another round trip
> 12:41:28.353  TEST: another round trip
> 12:41:30.361  TEST: another round trip
> ----- Activity in Foreground
> 12:41:30.369  TEST: coroutine awake

我该如何解决?

1-将代码从init移到suspend fun start()内部活动所调用的lifecycleScope.launchWhenStarted吗?

我得到相同的结果。我以为lifecycleScope进入背景时会取消其子协程,但是通过这种方法我得到了相同的Timber输出。

2-将我的ViewModel代码更改为:

private lateinit var job: Job

suspend fun startEmitting() {
    job = viewModelScope.launch {
        Timber.i("coroutine awake")
        while (true){
            delay(2_000)
            Timber.i("another round trip")
        }
    }
}
fun cancelJob(){
    if(job.isActive){
        job.cancel()
    }
}

而且,在我的活动中:

override fun onResume() {
    super.onResume()
    lifecycleScope.launch {
        viewModel.startEmitting()
    }
}
override fun onPause() {
    super.onPause()
    viewModel.cancelJob()
}

它很好,但是viewModelScope不是为我管理CoroutineScope的目的吗?我讨厌这个cancelJob逻辑。

解决此问题的最佳方法是什么?

android kotlin android-lifecycle kotlin-coroutines android-viewmodel
1个回答
0
投票

Kotlin无法为您取消无限操作。您需要在某处致电isActive。例如:while(isActive)

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