Android kotlin 中 SharedFlow 的使用

Viv*_*odi 19 android kotlin kotlin-flow kotlin-stateflow kotlin-sharedflow

嘿,我正在学习 kotlin 中的流程。我正在学习MutableStateFlowMutableSharedFlow。我尝试在现实世界的例子中学习MutableStateFlow。但我无法获得MutableSharedFlow示例,它更适合。我尝试了一些MutableStateFlow

例如,当我们从 api 获取数据时,我们可以使用 seal 类来进行相应的填充。

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()
} 
Run Code Online (Sandbox Code Playgroud)

设置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)
                    }
                )
 }

}
Run Code Online (Sandbox Code Playgroud)

活动.kt

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
                        }
                    }
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)

我都得到了MutableStateFlow 的例子。有人可以指导我如何在现实世界的示例中执行MutableSharedFlow吗?我也很好奇参数

  1. 重播

  2. 额外的缓冲容量

  3. 缓冲区溢出

谢谢

Ajm*_*mal 21

状态流

StateFlow 表示一个变化的值,您可以将这些变化作为流来监听。StateFlow 通常用于表示应用程序中某些内容的状态,例如应在 TextView 中显示的文本。StateFlow 类似于android 中的LiveData或反应式流中的主题

共享流

SharedFlow 代表一个值流,它可以像 StateFlow 一样被多次监听。但它实际上并没有“当前”值(尽管它可以有一个缓冲区)。SharedFlow 有一个可以配置的任意大小的缓冲区。SharedFlow 类似于反应式流中的Processor

为什么要使用它?

SharedFlow 的用途更为普遍,但它可以用于表示按钮触摸事件等。由于按钮触摸没有“当前”值并且实际上只是时间事件,因此 SharedFlow 会更合适。另一个例子是发送到扬声器的音频数据流。

参数

replay:这是 SharedFlow 将向新订阅者发送的缓冲区中的事件数。

extraBufferCapacity:这是 SharedFlow不会在缓冲区中发生的事件数

总缓冲区大小为replay+ extraBufferCapacity。两者的默认值都是 0。通常您需要其中之一,但也可以同时使用两者。

onBufferOverflow: 表示当缓冲区已满并且您尝试使用 时会发生什么情况emitBufferOverflow有三种可能的选项:

  • SUSPEND:这将使emit挂起,直到缓冲区有空间为止。这是默认设置。

  • DROP_LATEST:这将删除缓冲区中的最新值。

  • DROP_OLDEST:这将删除缓冲区中最旧的值。

由于默认缓冲区为零且溢出策略为挂起,因此emit将始终挂起将始终以默认参数

与 StateFlow 的关系

StateFlow一个 SharedFlow,但 SharedFlow 比 StateFlow 更通用。StateFlow 有点像重播缓冲区大小为 1 的 SharedFlow。但是使用 StateFlow,您还可以使用属性访问器语法轻松读取和写入该值,如下所示:

stateFlow.value = "hello"
val text = stateFlow.value
Run Code Online (Sandbox Code Playgroud)

用法

您听 SharedFlow 的方式与听 StateFlow 的方式相同,尽管在缓冲区方面有一些注意事项。要将值发送到 SharedFlow,您可以使用emit挂起函数或尽力tryEmit使用非挂起函数。

请注意,由于缓冲区为零,因此tryEmit 永远不会发出具有默认参数的值。只有在您知道缓冲区非零且溢出策略不为零的情况下,它才会真正正常工作SUSPEND

共享流的一个合理用例是将按钮按下发送到视图模型,如下所示:

stateFlow.value = "hello"
val text = stateFlow.value
Run Code Online (Sandbox Code Playgroud)

在实践中,使用中间回调流程可能比这种方式更好。


Sam*_*hen 4

MutableStateFlow与 类似MutableLiveData,两者都必须.value访问该值或更改该值。

MutableSharedFlow类似于SingleLiveEvent,用于观察瞬时状态变化。

更多示例和教程您可以观看此视频:https://youtu.be/6Jc6-INantQ