Комментарии 13
Например, чтоб результат приходил только в промежутке между onStart/onStop, а если приходит в бекграунде, то постился автоматически при переходе в фореграунд?
Если кратко, то из коробки никак:)
Сам по себе StateFlow никак не связан с Андроид и не знает о жизненных циклах приложения.
Единственное, что может работать — если collect запускать на скоупе либо lifecycleScope либо на скоупе ViewModel. Тогда "отмена" подписки будет происходить сама на onDestroy/onCleared.
А чтобы сделать аналогично LiveData — только самим ручками, либо возможно Гугл сделает что-то с этим сам.
Похожая (но немного перевернутая) ситуация и со StateFlow — сам StateFlow ничего не знает о lifecycle, но подписавшись на него вызовом collect() в рамках «нужного» coroutine-контекста мы обеспечим его правильную работу с lifecycle
Не совсем так.
StateFlow будет "знать" только о create/destroy. Загляните, например, внутрь реализации lifecycleScope.
LiveData же умеет не оповещать если в фоне..StateFlow такое сам не сможет, скойуп не закэнселится в этом случае.
lifecycleScope.launch {
whenStarted {
...
}
}
И да, StateFlow без coroutine-контекста не знает об изменениях состояния, так же как и LiveData без LifecycleOwner
Есть такое, но тут главное не путаться с "будет работать только в started-состоянии"
Лучше сказать, что стартанёт в started(created/resumed) состоянии, но cancel будет только в destroy.
Вы правы, давно не заглядывал в исходник Lifecycle.
Только там хитрее. Там используется специальный PausingDispatcher через который проходят все события и они либо выполняются, либо если состояние lifecycle иное, то просто стопается вся очередь и копится, а потом отдаётся.
Думал, там ещё тоже самое что и с ViewModel. Гляну и её, может тоже наконец-то что-то изменилось и в ней..
lifecycleScope.launchWhenResumed {
viewModel.loadingStateFlow
.collect { Log.d("MainFragment","Loading state: $it") }
}
Т.к. мы можем наблюдать значения только на скоупе onResume-onPause, или onCreate-onDestroy. А LiveData такого не умеет, так как по умолчанию она умеет слушать только в onStart-onStop.
P.S. ещё заметил интересную особенность StateFlow — когда постишь одно и то же значение несколько раз, то collect будет вызван только 1 раз
Пробуем и разбираемся с StateFlow