viewModelScope未取消 [英] viewModelScope not cancelled

查看:405
本文介绍了viewModelScope未取消的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

观看 Sean在Android(Google I/O'19)上的解释一样:

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

不幸的是,onCleared是在活动被杀死时调用的,而不是在其置于后台时调用的(当我们离开Activity ...时,背景正在移开"恕我直言^^).
我得到以下输出:

Unfortunately onCleared it's called when the activity is killed but not when it's put in background ("when we move away from the Activity...", background is "moving away" imho ^^).
And I get the following output:

> ---- 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移到lifecycleScope.launchWhenStarted内部活动所调用的suspend fun start()吗?

1 - Move the code from init to a suspend fun start() called by the activity inside a lifecycleScope.launchWhenStarted?

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

I get the same result. I thought lifecycleScope would cancel its child coroutines when it went to background, but I get the same Timber output with this approach.

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

2 - Change my ViewModel code to:

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逻辑.

Well it works but isn't the viewModelScope purpose to manage the CoroutineScope for me? I hate this cancelJob logic.

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

What's the best approach to deal with this?

推荐答案

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

Kotlin can't cancel an infinite operation for you. You need to call isActive somewhere. For example: while(isActive).

这篇关于viewModelScope未取消的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆