Использование 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 в реальных примерах. Также меня интересуют параметры

  1. воспроизвести

  2. дополнительный буфер емкости

  3. 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

Другие вопросы по тегам