StateFlow 和 LiveData 有啥区别?

Posted

技术标签:

【中文标题】StateFlow 和 LiveData 有啥区别?【英文标题】:What are the differences between StateFlow and LiveData?StateFlow 和 LiveData 有什么区别? 【发布时间】:2021-10-08 14:58:51 【问题描述】:

正如我在标题中提到的,我很好奇两者之间的一般差异。你能帮忙吗?由于网上有复杂的例子,我找不到具体的区别。

    在性能方面有何不同? 在哪些场景下有优势? 将 StateFlow 与 Kotlin Flow 结合使用是有利的。但是在使用 LiveData 的项目中不切换到 StateFlow 的风险是什么? Google 是否会弃用 LiveData? :)

【问题讨论】:

1.微不足道。 2. StateFlow 强制存在一个初始值(但您可以将 MutableLiveData 子类化以执行相同的操作),因此如果类型不可为空,则该值永远不会为空。 3. 我不明白这个问题。如何在不使用 Flow 的项目中使用 Flow? 4. 不明白你在问什么。 4. Google 是否会弃用 LiveData? 没有公开宣布他们计划弃用它。 StateFlow 实际上不能在 Java 中使用,所以我怀疑它会在未来几年的任何时候被弃用。 3.将 StateFlow 与 Kotlin Flow 结合使用是有利的。但是在使用 LiveData 的项目中不切换到 StateFlow 的风险是什么? 关于 2,我也认为 Flows 运算符比 LiveData 的转换更容易使用。 3. 我仍然不明白你在说什么将 StateFlow 与 Flow 一起使用。 StateFlow 只是 Flow 的一个子类型。这有点像说在具有 Ints 的项目中使用 Comparable 是有利的。不切换没有风险,除非您担心 LiveData 可能会很快被弃用。 【参考方案1】:

我刚刚切换到StateFlow,所以现在是我回答您问题的好时机。


在性能方面有什么区别?

老实说,我不知道,但既然它是由 KotlinAndroid 推动的,请相信他们 :)。


在哪些场景有优势?

    对于LiveData,您不必强制给出初始值,它可能最终会在init 中编写更多代码;但是对于StateFlow,你强制给出一个初始值(包括null),它可能会节省你的代码。

    对于LiveData,即使你给了一个初始值,当你访问它的value(见this)时,你仍然需要做Null Check,这有点烦人。但这不会发生在 StateFlow 上——它应该是这样的。

    对于LiveData,您无法轻松地观察ViewModel 内部的数据变化只是,您将使用observeForever(),here 中也提到了这一点。但是对于StateFlow 来说很简单,如下所示:

     class FirstViewModel() : ViewModel() 
         val uiScope = viewModelScope
    
         val name = MutableStateFlow("Sam")      //must have initial value
         //val name = MutableStateFlow<String?>(null)   //null is acceptable
    
         init 
             observeName()
         
    
         private fun observeName() = uiScope.launch     //must run in coroutine scope                                                       
             name.collect  name ->                      //for Fragment / Activity, use lifecycleScope.launch
                 //do your stuff
             
         
     
    

将 StateFlow 与 Kotlin Flow 结合使用是有利的。但是在使用 LiveData 的项目中不切换到 StateFlow 的风险是什么?

在使用 Java 的项目中不切换到 Kotlin 的风险是什么? :)


Google 是否会弃用 LiveData?

我会说是,他们会说不,不,因为“还没有大声说出来”:)。

【讨论】:

惊人的解释! 但是//do your stuff 块不会涉及更新用户界面吗?如何在视图模型中做到这一点,而不将视图传递给视图模型(违反 MVVM)或使用另一个可观察/回调(在这种情况下,拥有StateFlow 有什么意义?) @Matt Observing StateFlow/LiveData 并不意味着工作与 UI 相关,我可能想根据另一个 StateFlow/LiveData 的更改来更新变量,但我不希望那样暴露给Fragment/Activity的变量。 @SamChen 这听起来像是一个不寻常的用例,文档中的所有 Google 示例都有 StateFlow 直接更新 UI。我看不到StateFlow 的目的。听起来它与LiveData 相同,只是现在您必须在 Activity/Fragment 中处理您的协程(谷歌自己声称这是不好的做法)。 @Matt 这个视频可能会有所帮助:youtu.be/JnN6EFZ6DO8.

以上是关于StateFlow 和 LiveData 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

我们如何保存和恢复 Android StateFlow 的状态?

谁能取代Android的LiveData- StateFlow or SharedFlow?

不做跟风党,LiveData,StateFlow,SharedFlow 使用场景对比

不做跟风党,LiveData,StateFlow,SharedFlow 使用场景对比

谁能取代Android的LiveData- StateFlow or SharedFlow?

Jetpack MVVM 七宗罪之四: 使用 LiveData/StateFlow 发送 Events