概述
前言
LiveData 相信大家都非常熟悉了,但是由于协程与 Flow 的不断发展,之前所使用的技术也正在不断被替代,而 LiveData 的功能与 StateFlow 很相似,所以,很多人都在考虑使用 StateFlow 去替代 LiveData。
这里,我们就分析下,LiveData 与 StateFlow 的优缺点,以及我们该如何抉择。
LiveData 与 StateFlow 的区别
关于 LiveData 与 StateFlow,网上说的最多的区别,其实就是「官方指导文档」中所讲解的这两点,这里我直接搬运过来:
- StateFlow 需要将初始状态传递给构造函数,而 LiveData 不需要。
- 当 View 进入 STOPPED 状态时,LiveData.observe() 会自动取消注册使用方,而从 StateFlow 或任何其他数据流收集数据的操作并不会自动停止。如需实现相同的行为,您需要从 Lifecycle.repeatOnLifecycle 块收集数据流。
关于第一点,对于 LiveData 与 StateFlow 的使用并不能起决定性的作用,因为在创建 StateFlow 的时候,你可以传入 null 进去,就像这样:
val stateFlow = MutableStateFlow<String?>(null)
而在第二点中,LiveData 会跟生命周期绑定,能够自动取消注册,这个看起来是优点,但是,其实也是一个缺点。
为什么这样说?
因为对于数据而言,它其实并不需要关心调用者的生命周期,它只需要负责数据读取与存储即可,所以,为什么要考虑数据使用者的状态?这时,可能有的人会说,“数据基本上都是与视图进行绑定,所以,视图消失的时候,数据自然也用不上了,所以自动取消很好啊”,确实,这样的确很好,但是有时在数据读取的之后,我们并非希望它每次都是在刷新视图,而是进行存储、写日志、上报等他用,而这时,自动取消就会变成了一种负担。
因此,数据与取消绑定应该剥离开来,可以用统一的方式获取数据,在数据进行调用前,再依据情况判断是否与生命周期进行关联。这个判断并非为代码判断,而是开发者的逻辑判断,因为只有开发者清楚,这些代码是否需要与生命周期相关联,若要关联,可以使用 lifecycleScope 或 ViewModelScope 进行解决,这里就以 lifecycleScope 为主进行说明。
解决有两种方式:
- lifecycleScope.launch
- repeatOnLifecycle
lifecycleScope.launch
launch 里面的代码由 lifecycleScope 进行控制,若对象生命周期结束了,则 launch 里面的代码也会被取消。
repeatOnLifecycle
这个主要用于当对象运行到生命周期的某个阶段的时候,就自动触发相应的功能:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
GlobalScope.launch {
repeatOnLifecycle(Lifecycle.State.RESUMED){
println("repeatOnLifecycle RESUMED 已被执行")
}
}
}
override fun onResume() {
super.onResume()
println("onResume 已被执行")
}
}
日志输出:
I/System.out: onResume 已被执行
I/System.out: repeatOnLifecycle RESUMED 已被执行
当然,也可以使用以下方法来实现:
lifecycleScope.launchWhenCreated { }
lifecycleScope.launchWhenStarted { }
lifecycleScope.launchWhenResumed { }
被动回调与主动收集
上面说的只是「官方指导文档」所提及的「LiveData 与 StateFlow 的区别」,但是,我觉得这两种说法,还是不能决定我该用 LiveData 还是 StateFlow,因为关于 LiveData 的生命周期的优势,可以使用 lifecycleScope+StateFlow
解决。所以,我从另外一个角度谈谈我是怎么理解与判断的,那就是被动回调与主动收集。
被动回调
相信了解过观察者模式的同学都知道,当被观察者有改动的时候,就会通知观察者,但是,其实在这个时候,观察者只知道被观察者有改动了,并不清楚外部的情况,例如生命周期走到哪里了?是什么地方触发了被观察者去更新等等,所以,我认为 LiveData 这种更新数据方式为被动回调。
主动收集
对于 StateFlow 而言,并不是每次数据更新都会回调到 collect 中了,而是在 collect 的时候,看看最新数据是哪些,然后进行读取,等 collect 运行完后,即使数据更新了,也不会回调到 collect 中,需要开发者自己再次调用 collect,才能再次获取数据。
所以,对于 StateFlow,其实更像一个单独的数据管理,核心并不在于观察者模式,更强调于用户主动去获取数据,所以,我认为这种方式为主动收集。
总结
由于被动回调与主动收集的区别,这时我们就很清晰什么时候该用哪种方式了。
假如数据与视图进行强绑定,或者说,一旦数据改变了,需要更改多处地方 UI,那么,这时使用 LiveData 更合适,但是,假如你只想对数据进行管理,清楚每次数据刷新的时机,那么使用 StateFlow 更合适。
最后
以上就是柔弱黄豆为你收集整理的LiveData 与 StateFlow,我该用哪个?的全部内容,希望文章能够帮你解决LiveData 与 StateFlow,我该用哪个?所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复