2

嘿,我正在学习 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()
} 

SettingsViewModel.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)
                    }
                )
 }

}

活动.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
                        }
                    }
                }
            }
        }

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

  1. 重播

  2. 额外缓冲容量

  3. onBufferOverflow

谢谢

4

2 回答 2

0

状态流

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

共享流

SharedFlow 代表一个值流,它可以像 StateFlow 一样被多次监听。但它并没有真正的“当前”值(虽然它可以有一个缓冲区)。SharedFlow 有一个可以配置的任意大小的缓冲区。SharedFlow 类似于反应流中的处理器

为什么要使用它?

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

参数

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

extraBufferCapacity:这是 SharedFlow不会向新订阅者发出的缓冲区中的事件数。

总缓冲区大小为replay+ extraBufferCapacity。两者的默认值为 0。通常你想要一个或另一个,但你可以同时使用。

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

  • SUSPEND:这将使发射暂停,直到缓冲区中有空间。这是默认设置。

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

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

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

与 StateFlow 的关系

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

stateFlow.value = "hello"
val text = stateFlow.value

用法

你听 SharedFlow 的方式与你做 StateFlow 的方式相同,尽管在缓冲区方面有一些警告。要将值发送到 SharedFlow,您可以使用emit挂起函数或非挂起函数的最大努力tryEmit

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

共享流的一个合理用例是将按钮按下发送到这样的视图模型:

class WeatherViewModel {
    val refreshEvents = SharedFlow<Unit>(
        extraBufferCapacity = 1, 
        onBufferOverflow = BufferOverflow.DROP_OLDEST
    )
}


fun onButtonPress() {
    refreshEvents.tryEmit(Unit)
}

在实践中,使用中间回调流可能比这样做更好。

于 2022-02-20T02:47:37.530 回答
0

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

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

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

于 2022-02-10T17:25:03.403 回答