StateFlow和LiveData之间有什么区别?

17
如标题所述,我对这两者之间的一般区别很好奇。你能帮忙解答吗?我在网上找不到具体的区别,因为有很多复杂的例子。
  1. 在性能方面有什么区别?
  2. 在哪些场景下它提供了优势?
  3. 在使用 Kotlin Flow 时,使用 StateFlow 有什么好处。但是在使用 LiveData 的项目中不切换到 StateFlow 会有什么风险?
  4. Google 是否正在弃用 LiveData?:)

2
  1. 可以忽略的。
  2. StateFlow 强制存在初始值(但您可以子类化 MutableLiveData 来执行相同的操作),因此如果类型不可为空,则该值永远不会为 null。
  3. 我不明白这个问题。在不使用 Flow 的项目中如何使用 Flow?
  4. 不明白你在问什么。
- Tenfour04
  1. Google 是否正在弃用 LiveData?
- Arda Kazancı
1
目前没有公开宣布他们计划弃用它。StateFlow 无法在 Java 中实际使用,因此我怀疑它在未来几年内会被弃用。 - Tenfour04
  1. 在使用 Kotlin Flow 时,使用 StateFlow 是有优势的。但是在一个使用 LiveData 的项目中不切换到 StateFlow 会有什么风险?
- Arda Kazancı
2
关于第二点,我也认为Flows操作符比LiveData的转换要容易得多。第三点,我仍然不明白你在说什么关于使用StateFlow与Flow。StateFlow只是Flow的一个子类型。这有点像在一个项目中使用Comparable对Ints进行排序是有优势的。除非你担心LiveData可能很快就会被弃用,否则没有不切换的风险。 - Tenfour04
我对你的回答感到满意。谢谢。3. 抱歉没有完全解释清楚问题。 - Arda Kazancı
1个回答

19
我刚刚转向使用StateFlow,所以这是我回答你的问题的绝佳时机。

在性能方面有何区别?

老实说,我不知道,但由于它是由KotlinAndroid推动的,所以请相信它们 :)


在哪些情况下它会提供优势?

  1. For LiveData you are not forced to give an initial value, it may end up writing more code in init{}; But for StateFlow you are Forced to give an initial value (including null), it may save your code a bit.

  2. For LiveData even if you give an initial value, you still need to do Null Check when you access its value (see this), it's kind of annoying. But that's not gonna happen on StateFlow - it will be what it should be.

  3. For LiveData you cannot easily, or elegantly observe data changes JUST inside ViewModel, you are gona use observeForever() which is also mentioned in here. But for StateFlow it's easy, do it like following:

     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
             }
         }
     }
    

使用Kotlin Flow和StateFlow是有优势的。但在使用LiveData的项目中不切换到StateFlow会有什么风险?

在使用LiveData的项目中不切换到StateFlow会有什么风险呢?这就好比在使用Java的项目中不切换到Kotlin一样,你懂的 :)


Google是否已经废弃LiveData?

我想说是的,但他们可能会说还没有公开宣布 :)


惊人的解释! - Abed
但是//do your stuff块不会涉及到更新UI吗?在ViewModel中如何做到这一点,既不需要将视图传递给ViewModel(违反MVVM),也不使用另一个可观察的/回调函数(那么,使用StateFlow有什么意义呢?)。 - Matt
@Matt 观察 StateFlow/LiveData 并不意味着工作与 UI 相关,我可能想根据另一个 StateFlow/LiveData 的变化更新一个变量,但我不希望该变量暴露给 Fragment/Activity - Sam Chen
2
@SamChen,这听起来像是一个不寻常的用例,在文档中,Google所有的示例都是直接使用StateFlow更新UI。我不明白StateFlow的目的所在。它听起来与LiveData相同,只是现在你必须在Activity/Fragment中处理你的协程(而Google本身声称这是不好的实践)。 - Matt
@Matt 这个视频可能会有所帮助:https://youtu.be/JnN6EFZ6DO8。 - Sam Chen
2
@SamChen,我终于有机会看了这个视频,但仍然不理解StateFlow的好处。他唯一给出的真正论据是现在你可以将Fragment作为生命周期所有者而不是viewLifecycleOwner进行传递。我认为这只是又一个没有任何益处的Android潮流。 - Matt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接