Поток сопрограмм Kotlin не отменяется

#kotlin #kotlin-coroutines #android-viewmodel #kotlin-flow

#kotlin #kotlin-сопрограммы #android-viewmodel #kotlin-flow

Вопрос:

У меня есть класс UseCase с методом, который возвращает поток

 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 вызывается с помощью CoroutineScope ViewModel, разве он не должен быть отменен и больше не выдавать значения?

Область ViewModel реализована в BaseViewModel, из которой моя ViewModel расширяется следующим образом:

абстрактный класс BaseViewModel( private val dispatcherProvider: DispatcherProvider) : ViewModel(), CoroutineScope {

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

private val job = SupervisorJob()

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

}

Я забыл добавить какую-то пользовательскую логику отмены или пропустил что-то другое?

Ответ №1:

Если область действия вашей ViewModel является жизненным циклом Activity ViewModelProvider(requireActivity()).get(YOUR_VIEWMODEL::class.java) , то onCleared она не будет вызвана, если ваша Activity не будет уничтожена, но не с изменениями вращения.

Во-первых, убедитесь, что вызывается onCleared() , если он не вызывается, вы можете вызвать его любым методом жизненного цикла фрагмента или действия.

Комментарии:

1. Да, вы были правы, я пропустил это. Моя ViewModel была ограничена моим жизненным циклом activity, и, конечно, onCleared() не вызывался, поскольку при переходе к другому фрагменту жизненный цикл activity не изменился.