当前位置:网站首页>LiveData 与 StateFlow,我该用哪个?
LiveData 与 StateFlow,我该用哪个?
2022-06-11 08:42:00 【码中之牛】
前言
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 更合适。
边栏推荐
- Cron expressions in scheduled tasks
- EN45545-2 R26垂直燃烧测试介绍
- Classical graph theory, depth first and breadth first, topology, prim and krukal, it's time to review
- Supplement 2: circle returning to origin
- 显示屏DIN 4102-1 Class B1防火测试要求
- 面试官问了四个问题,总结了4个经验
- [node] NPM part
- En45545-2 R26 vertical combustion test introduction
- Wood board ISO 5660-1 heat release rate mapping test
- Hibernate L2 cache
猜你喜欢

Cyclic sort

Can not connect to local MySQL server through socket ‘/tmp/mysql. sock (2)‘

【CVPR2022】QueryDet论文精读

Redis6 entry-level tutorial. There are integration cases. You can directly see the integration cases. It is easy to get started

MySQL advanced features, you can read more about it and meet the interview

进程间的通信
![[cvpr2022] intensive reading of querydet papers](/img/10/a48e2c877946a1b9da71ce6e9546f7.png)
[cvpr2022] intensive reading of querydet papers

Sword finger offer 62 The last remaining number in the circle

M1 芯片指南:M1、M1 Pro、M1 Max 和 M1 Ultra

命名实体识别之CRF的实现方式
随机推荐
K8s application (IV) - build a redis5 cluster (for direct external access)
盘它!用「飞项」轻松管理各类型项目
PVC plastic sheets BS 476-6 determination of flame propagation properties
BFS on tree (tree breathing first search)
室内膨胀型防火涂料根据BS 476-21 耐火标准测定需要符合几项?
PVC 塑料片BS 476-6 火焰传播性能测定
Heap can also be regarded as a tree structure. It is specified that the root node must be greater than or less than the left and right child nodes, but the size order of the left and right child nodes
(2) Analysis of AAC source code from the perspective of architecture design - my livedata
GCC AVR (ATMEL studio+ AVR studio) how to define the structure array in the program memory (flash) space and read it
Using docker compose to build redis5 cluster
vagrant 安装踩坑
[software tool] installation ffmpeg
马志强:语音识别技术研究进展和应用落地分享丨RTC Dev Meetup
ActiveMQ简单教程,适合初学者,学习笔记yyds
How to solve the MySQL deadlock problem? Recitation version
EN 45545-2:2020 T11烟毒性检测
Sword finger offer 21 Adjust array order so that odd numbers precede even numbers
经典图论,深度优先和广度优先,拓扑,Prim和Krukal,该来温习啦
Zookepper===> animal management system
Web design and website planning assignment 11 game selection form