繁体   English   中英

SharedFlow 在 Android kotlin 中的使用

[英]Use of SharedFlow in Android kotlin

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

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

登录状态.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()
} 

设置视图模型.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

谢谢

状态流

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

共享流

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

为什么要使用它?

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

参数

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

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

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

onBufferOverflow :表示当缓冲区已满并且您尝试使用emit时会发生什么。 BufferOverflow有三种可能的选择:

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

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

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

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

与 StateFlow 的关系

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

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

用法

您听 SharedFlow 的方式与听 StateFlow 的方式相同,尽管在涉及缓冲区时有一些注意事项。 要将值发送到 SharedFlow,您可以使用从挂起tryEmit emit或从非挂起 function 尝试发射。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM