#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 не изменился.