Kotlin-Flow常用封装类:StateFlow的使用

Kotlin中StateFlow的使用

StateFlow 是 Flow 的实现,是一个特殊的流,默认的 Flow 是冷流,而StateFlow 是热流,和 LiveData 比较类似。关于冷热流后面一期 SharedFlow 会详细说明。

使用 StateFlow 替代 LiveData 应该是目前很多开发者的呼吁了,确实 LiveData 的功能 StateFlow 都能实现,可以说是 LiveData 的升级版。

StateFlow的特点

官方推荐当暴露 UI 的状态给视图时,应该使用 StateFlow。这是一种安全和高效的观察者,专门用于容纳 UI 状态。

一、StateFlow的使用

方式一,我们自己 new 出来

一般我们再ViewModel中定义读写分类的StateFlow

@HiltViewModelclass Demo4ViewModel @Inject constructor(    val savedState: SavedStateHandle) : BaseViewModel() {    private val _searchFlow = MutableStateFlow("")    val searchFlow: StateFlow = _searchFlow    fun changeSearch(keyword: String) {        _searchFlow.value = keyword    }}

在Activity中我们就可以像类似 LiveData 一样的使用 StateFlow

    private fun testflow() {       mViewModel.changeSearch("key")    }    override fun startObserve() {        lifecycleScope.launchWhenCreated {            mViewModel.searchFlow.collect {                YYLogUtils.w("value $it")            }        }    }

方式二,通过一个 冷流 Flow 转换为 StateFlow

    val stateFlow = flowOf(1, 2, 3).stateIn(            scope = lifecycleScope,//            started = WhileSubscribed(5000, 1000),//            started = Eagerly,            started = Lazily,            initialValue = 1        )        lifecycleScope.launch {            stateFlow.collect {            }        }

几个重要参数的说明如下

二、替代LiveData

不管是普通的 ViewModel 观察订阅模式,在Activity中订阅,还是DataBinding的模式,我们都可以使用StateFlow来代替ViewModel

    val withdrawMethod = MutableStateFlow(0)    

为什么我们需要用StateFlow来代替LiveData,或者说LiveData有什么缺点?

LiveData vs Flow

先上代码,看看它们的用法与差异

ViewModel的代码

@HiltViewModelclass Demo4ViewModel @Inject constructor(    val savedState: SavedStateHandle) : BaseViewModel() {    private val _searchLD = MutableLiveData()    val searchLD: LiveData = _searchLD    private val _searchFlow = MutableStateFlow("")    val searchFlow: StateFlow = _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){            YYLogUtils.w("value $it")        }        lifecycleScope.launchWhenCreated {            mViewModel.searchFlow.collect {                YYLogUtils.w("value $it")            }        }    }

可以看到基本的使用几乎是没有差异,在DataBinding中同样的是都能使用。那么它们有哪些差异呢?

它们相同的地方:

  1. 仅持有单个且最新的数据
  2. 自动取消订阅
  3. 提供「可读可写」和「仅可读」两个版本收缩权限
  4. 配合 DataBinding 实现「双向绑定」

相比StateFlow ,LiveData的确定:

  1. LiveData在某些特定的场景下会丢失数据
  2. LiveData 只能在主线程不能方便地支持异步化
  3. LiveData 的数据变换能力远远不如 Flow
  4. LiveData 粘性问题解决需要额外扩展
  5. LiveData 多数据源的合流能力远远不如 Flow
  6. LiveData 默认不支持防抖,值没有变化也会通知

这么惨,那我们开发是不是要放弃LiveData了?

恰恰不是!

如果大家全部是Koltin代码开发,那么是可以用Flow,这是基于Kotlin代码,基于协程实现的,但是现在很多项目还是 Java 语言开发的。那么LiveData还是很香的。

其二是LiveData的学习成本与 协程、Flow 的学习成本不可同日而语,开发项目是整个团队的事情,不能说你一个人会一个人用,目前LiveData的简单学习成本是很有优势的。

只是我们需要在一些特定的场景慎重使用postValue,比如数据比较秘籍的场景,我们尽量使用setValue方法。

总结

如果大家的项目的语言是 Kotlin ,并且小组成员都会 Flow 。那么我推荐你们使用StateFlow 替代LiveData 。如果不是,那么 LiveData 是你最好的选择。

谷歌也只是推荐使用Flow替代LiveData。但是并没有说打算放弃 LiveData 。并且 LiveData 与 StateFlow 都有各自的使用场景,不需要担心 LiveData的 使用。

本文我们只是简单的对比,关于StateFlow 与 SharedFlow 和LiveData 三者的差异与选择,后面等SharedFlow那一期详细的讲解。

为什么很多东西都要等SharedFlow,是因为 SharedFlow 是 StateFlow 的基础,StateFlow 像是 SharedFlow 的‘青春版’。很多东西需要讲完 SharedFlow 才能把知识点串起来,期待一下。

作者:newki
链接:https://juejin.cn/post/7127082531358244900
来源:稀土掘金

展开阅读全文

页面更新:2024-05-11

标签:冷流   观察者   热流   可读   场景   差异   类似   作用   常用   代码   数据

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top