【问题标题】:Kotlin coroutines Flow is not canceledKotlin 协程流程未取消
【发布时间】:2021-01-04 06:31:49
【问题描述】:

我有一个 UseCase 类,其方法返回 Flow

fun startTimeTicker(startTime: Long) = flow {
    val countdownStart = System.currentTimeMillis()
    for (currentTime in countdownStart..startTime step ONE_SECOND_MILLIS) {
        .... irrelevant ...
        emit("Some String")
        delay(ONE_SECOND_MILLIS)
    }
}

我正在像这样在 ViewModel 中收集发布日期

private fun startCollecting(startTime: Long) = launch {
    matchStartTimerUseCase.startTimeTicker(startTime).collect {
        _startTimeCountdown.postValue(it)
    }
}

我的片段正在观察 LiveData 并显示值。它按预期工作,直到我离开屏幕。由于 launch 是用 ViewModel 的 coroutineScope 调用的,它不应该被取消并且不再发出值吗?

ViewModel 的范围是在 BaseViewModel 中实现的,我的 ViewModel 从中扩展如下:

抽象类 BaseViewModel( 私人 val dispatcherProvider: DispatcherProvider ) : ViewModel(), CoroutineScope {

override val coroutineContext: CoroutineContext
    get() = job + dispatcherProvider.provideUIContext()

private val job = SupervisorJob()

override fun onCleared() {
    super.onCleared()
    job.cancel()
}

}

我是否忘记添加一些自定义取消逻辑或遗漏其他内容?

【问题讨论】:

    标签: kotlin kotlin-coroutines android-viewmodel kotlin-flow


    【解决方案1】:

    如果您的 ViewModel 的范围是 Activity 的生命周期 ViewModelProvider(requireActivity()).get(YOUR_VIEWMODEL::class.java),则不会调用 onCleared,除非您的 Activity 被销毁,但不会发生旋转更改。

    首先,确保 onCleared() 被调用,如果没有被调用,你可以调用它任何 Fragment 或 Activity 的生命周期方法。

    【讨论】:

    • 是的,你是对的,我错过了。我的 ViewModel 被限定为我的活动生命周期,当然 onCleared() 没有被调用,因为导航到其他片段时活动生命周期没有变化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-02
    • 2019-09-30
    • 2019-06-19
    • 2020-04-28
    • 1970-01-01
    • 1970-01-01
    • 2020-04-12
    相关资源
    最近更新 更多