在这篇文章中,您将学到如何把数据流暴露给视图、如何收集数据流,以及如何通过调优来适应不同的需求。
LiveData 就做了一件事并且做得不错: 它在 缓存最新的数据 和感知 Android 中的生命周期的同时将数据暴露了出来。稍后我们会了解到 LiveData 还可以 启动协程 和 创建复杂的数据转换,这可能会需要花点时间。
接下来我们一起比较 LiveData 和 Kotlin 数据流中相对应的写法吧:
#1: 使用可变数据存储器暴露一次性操作的结果
这是一个经典的操作模式,其中您会使用协程的结果来改变状态容器:
△ 将一次性操作的结果暴露给可变的数据容器 (LiveData)
class MyViewModel {
private val _myUiState = MutableLiveData<Result>(Result.Loading)
val myUiState: LiveData<Result> = _myUiState
// 从挂起函数和可变状态中加载数据
init {
viewModelScope.launch {
val result = …
_myUiState.value = result
}
}
}
如果要在 Kotlin 数据流中执行相同的操作,我们需要使用 (可变的) StateFlow (状态容器式可观察数据流):
△ 使用可变数据存储器 (StateFlow) 暴露一次性操作的结果
class MyViewModel {
private val _myUiState = MutableStateFlow<Result>(Result.Loading)
val myUiState: StateFlow<Result> = _myUiState
// 从挂起函数和可变状态中加载数据
init {
viewModelScope.launch {
val result = …
_myUiState.value = result
}
}
}
StateFlow 是 SharedFlow 的一个比较特殊的变种,而 SharedFlow 又是 Kotlin 数据流当中比较特殊的一种类型。StateFlow 与 LiveData 是最接近的,因为:
-
它始终是有值的。
-
它的值是唯一的。
-
它允许被多个观察者共用 (因此是共享的数据流)。
-
它永远只会把最新的值重现给订阅者,这与活跃观察者的数量是无关的。