赞
踩
在协程中,与仅返回单个值的挂起函数相反,数据流可按顺序发出多个值。数据流以协程为基础构建,可提供多个值。从概念上来讲,数据流是可通过异步方式进行计算处理的一组数据序列。所发出值的类型必须相同。
来源标注:Android 上的 Kotlin 数据流 | Android Developers
书接上篇:
Android Kotlin知识汇总(二)最佳实践-CSDN博客Android Jetpack之LiveData 使用及源码_android livedata源码-CSDN博客Android Kotlin知识汇总(二)最佳实践-CSDN博客
在 Android 中,StateFlow
非常适合需要让可变状态保持可观察的类。
StateFlow 是 Flow 的实现。默认的 Flow 是冷流,而StateFlow 是热流和 LiveData 类似。
使用 StateFlow 替代 LiveData 应该是目前很多开发者的呼吁了,确实 LiveData 的功能 StateFlow 都能实现,可以说是 LiveData 的升级版。
但请注意,StateFlow
和 LiveData 的行为确实有所不同:
StateFlow
需要将初始状态传递给构造函数,而 LiveData
不需要。STOPPED
状态时,LiveData.observe()
会自动取消注册使用方,而从 StateFlow
或任何其他数据流收集数据的操作并不会自动停止。StateFlow是一种单数据更新的热流,通过emit方法更新StateFlow的数据,通过value属性可以获取当前的数据。
设计中,关键讲一下MutableStateFlow接口。它接口继承自StateFlow接口,并在此基础上定义了一个新方法compareAndSet, 即通过CAS的方式更新value。代码如下:
- public interface MutableStateFlow<T> : StateFlow<T>, MutableSharedFlow<T> {
- // 当前数据
- public override var value: T
- // 如果except与value相等,则将value更新为update,并返回true
- // 如果except与value不相等,不做任何操作,直接返回false
- public fun compareAndSet(expect: T, update: T): Boolean
- }
在Activity中像类似LiveData 一样的使用 StateFlow。
- class DemoViewModel @Inject constructor(val savedState: SavedStateHandle) : BaseViewModel() {
- private val _searchFlow = MutableStateFlow("")
- val searchFlow: StateFlow<String> = _searchFlow
- fun changeSearch(keyword: String) {
- _searchFlow.value = keyword
- }
- }
- private fun testflow() {
- mViewModel.changeSearch("key")
- }
- override fun startObserve() {
- lifecycleScope.launchWhenCreated {
- mViewModel.searchFlow.collect {
- LogUtils.w("value $it")
- }
- }
- }

通过一个 冷流 Flow 转换为 StateFlow 。
- val stateFlow = flowOf(1, 2, 3).stateIn(
- scope = lifecycleScope,
- started = Lazily,
- initialValue = 1
- )
- lifecycleScope.launch {
- stateFlow.collect {}
- }
先看看它们的代码的用法。
- class DemoViewModel @Inject constructor(val savedState: SavedStateHandle) : BaseViewModel() {
- private val _searchLD = MutableLiveData<String>()
- val searchLD: LiveData<String> = _searchLD
-
- private val _searchFlow = MutableStateFlow("")
- val searchFlow: StateFlow<String> = _searchFlow
-
- fun changeSearch(keyword: String) {
- _searchFlow.value = keyword
- _searchLD.value = keyword
- }
- }
Activity中触发与接收事件:
- private fun testflow() {
- mViewModel.changeSearch("key")
- }
- override fun startObserve() {
- mViewModel.searchLD.observe(this){
- LogUtils.w("value $it")
- }
-
- lifecycleScope.launchWhenCreated {
- mViewModel.searchFlow.collect {
- LogUtils.w("value $it")
- }
- }
- }
可以看到,代码使用上十分类似。
注意:特定的场景慎重使用postValue。比如数据密集的场景,尽量使用setValue方法。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。