Использование SharedFlow в Android kotlin
Привет, я изучаю поток в Котлине. Я изучаю MutableStateFlow и MutableSharedFlow . Я пытался изучить MutableStateFlow на примере реального мира. Но я не могу получить пример MutableSharedFlow , где он больше подходит. Я попробовал немного MutableStateFlow
Например, когда мы извлекаем данные из API, мы можем использовать класс уплотнения для соответствующего заполнения.
LoggedState.kt
sealed class LoggedState {
data class OnSuccess(val data: List<XYZ>) : LoggedState()
object OnEmpty : LoggedState()
data class IsLoading(val isLoading: Boolean = true) : LoggedState()
data class OnError(val message: String) : LoggedState()
}
НастройкиViewModel.kt
class SettingsViewModel : ViewModel() {
var loggedMutableStateFlow = MutableStateFlow<LoggedState>(LoggedState.OnEmpty)
fun fetchData(){
val result = dataRepository.getLogged()
result.handleResult(
onSuccess = { response ->
val data = response?.items
if (!data.isNullOrEmpty()) {
loggedMutableStateFlow.value = LoggedState.OnSuccess(data)
} else {
loggedMutableStateFlow.value = LoggedState.OnEmpty
}
},
onError = {
loggedMutableStateFlow.value = LoggedState.OnError(it.message)
}
)
}
}
Активит.кт
lifecycleScope.launchWhenCreated {
repeatOnLifecycle(Lifecycle.State.CREATED) {
viewModel.loggedMutableStateFlow.collect { state ->
when (state) {
is LoggedState.OnEmpty -> {
// view gone
}
is LoggedState.OnSuccess -> {
// show ui
}
is LoggedState.IsLoading -> {
// show spinner
}
is LoggedState.OnError-> {
// show error message
}
}
}
}
}
Я все получаю пример MutableStateFlow . Может ли кто-нибудь помочь мне, как сделать MutableSharedFlow в реальных примерах. Также меня интересуют параметры
воспроизвести
дополнительный буфер емкости
onBufferOverflow
Спасибо
2 ответа
Государственный поток
StateFlow представляет значение, которое изменяется, и вы можете прослушивать эти изменения в виде потока. StateFlow обычно используется для представления состояния чего-либо в вашем приложении, например, текста, который должен отображаться в TextView. StateFlow похож на LiveData в Android или Subjects в реактивных потоках.
Общий поток
SharedFlow представляет собой поток значений, и его можно прослушивать несколько раз, как и StateFlow. Но на самом деле у него нет «текущего» значения (хотя он может иметь буфер). SharedFlow имеет буфер произвольного размера, который вы можете настроить. SharedFlow похож на Processor в реактивных потоках.
Зачем это использовать?
Использование SharedFlow является более общим, но его можно использовать, например, для представления событий касания кнопки. Поскольку касания кнопок не имеют «текущего» значения и на самом деле являются просто событиями во времени, SharedFlow был бы более подходящим. Другой пример — поток аудиоданных, поступающих на динамик.
Параметры
: это количество событий из буфера, которые SharedFlow будет передавать новым подписчикам.
: это количество событий в буфере, которое SharedFlow не будет отправлять новым подписчикам.
Общий размер буфера
replay
+
extraBufferCapacity
. По умолчанию 0 для обоих. Обычно вы хотите один или другой, но вы можете использовать оба.
onBufferOverflow
: представляет, что происходит, когда буфер заполнен, и вы пытаетесь использовать . Есть три возможных варианта BufferOverflow:
: Это заставит излучение приостановиться, пока в буфере не будет места. Это значение по умолчанию.
DROP_LATEST
: Это удалит последнее значение в буфере.DROP_OLDEST
: это удалит самое старое значение в буфере.
Поскольку буфер по умолчанию равен нулю, а стратегия переполнения — приостановка, emit всегда будет приостанавливаться с параметрами по умолчанию.
Отношения с StateFlow
StateFlow — это SharedFlow, но SharedFlow более общий, чем StateFlow. StateFlow похож на SharedFlow с размером буфера воспроизведения 1. Но с помощью StateFlow вы можете дополнительно легко читать и записывать это значение с помощью синтаксиса доступа к свойствам, подобного этому:
stateFlow.value = "hello"
val text = stateFlow.value
Применение
Вы слушаете SharedFlow так же, как и StateFlow, хотя и с некоторыми оговорками, когда речь идет о буферах. Чтобы отправить значения в SharedFlow, вы можете использовать
emit
из функции приостановки или максимальное усилие из функции без приостановки.
Обратите внимание, что
tryEmit
никогда не выдаст значение с параметрами по умолчанию, поскольку буфер равен нулю. Это будет действительно работать правильно только в тех случаях, когда вы знаете, что буфер не равен нулю, а стратегия переполнения не работает.
SUSPEND
.
Разумным вариантом использования общего потока является отправка нажатий кнопок в модель представления следующим образом:
class WeatherViewModel {
val refreshEvents = SharedFlow<Unit>(
extraBufferCapacity = 1,
onBufferOverflow = BufferOverflow.DROP_OLDEST
)
}
fun onButtonPress() {
refreshEvents.tryEmit(Unit)
}
На практике, вероятно, лучше использовать промежуточный callbackFlow , чем делать это таким образом.
MutableStateFlow
похоже на
MutableLiveData
, как есть
.value
для доступа к значению или для изменения значения.
MutableSharedFlow
похоже на
SingleLiveEvent
, используемый для наблюдения за мгновенными изменениями состояния.
Еще один пример и учебник вы можете посмотреть в этом видео: https://youtu.be/6Jc6-INantQ