- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章官方推荐 Flow 取代 LiveData,有必要吗?由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
打开Android架构组件页面,我们可以发现一些最新发布的jetpack组件,如Room,DataStore, Paging3,DataBinding 等都支持了Flow。Google开发者账号最近也发布了几篇使用Flow的文章,比如:从 LiveData 迁移到 Kotlin 数据流看起来官方在大力推荐使用Flow取代LiveData,那么问题来了,有必要吗?
我LiveData用得好好的,有必要再学Flow吗?本文主要回答这个问题,具体包括以下内容:
本文具体目录如下所示:
要了解LiveData的不足,我们先了解下LiveData为什么被引入 。
LiveData 的历史要追溯到 2017 年。彼时,观察者模式有效简化了开发,但诸如 RxJava 一类的库对新手而言有些太过复杂。为此,架构组件团队打造了 LiveData: 一个专用于 Android 的具备自主生命周期感知能力的可观察的数据存储器类。 LiveData被有意简化设计,这使得开发者很容易上手;而对于较为复杂的交互数据流场景,建议您使用 RxJava,这样两者结合的优势就发挥出来了 。
可以看出,LiveData就是一个简单易用的,具备感知生命周期能力的观察者模式 。
它使用起来非常简单,这是它的优点,也是它的不足,因为它面对比较复杂的交互数据流场景时,处理起来比较麻烦.
我们上文说过LiveData结构简单,但是不够强大,它有以下不足 。
关于LiveData只能在主线程更新数据,有的同学可能要问,不是有postValue吗?其实postValue也是需要切换到到主线程的,如下图所示:
这意味着当我们想要更新LiveData对象时,我们会经常更改线程(工作线程→主线程),如果在修改LiveData后又要切换回到工作线程那就更麻烦了,同时postValue可能会有丢数据的问题.
Flow 就是 Kotlin 协程与响应式编程模型结合的产物,你会发现它与 RxJava 非常像,二者之间也有相互转换的 API,使用起来非常方便.
为什么引入Flow,我们可以从Flow解决了什么问题的角度切入 。
LiveData不支持线程切换,所有数据转换都将在主线程上完成,有时需要频繁更改线程,面对复杂数据流时处理起来比较麻烦.
而RxJava又有些过于麻烦了,有许多让人傻傻分不清的操作符,入门门槛较高,同时需要自己处理生命周期,在生命周期结束时取消订阅 。
可以看出,Flow是介于LiveData与RxJava之间的一个解决方案,它有以下特点 。
关于Flow的使用,比较简单,有兴趣的同学可参阅文档:Flow文档 。
我们上面介绍过,Flow 是冷流,什么是冷流?
冷流 :只有订阅者订阅时,才开始执行发射数据流的代码。并且冷流和订阅者只能是一对一的关系,当有多个不同的订阅者时,消息是重新完整发送的。也就是说对冷流而言,有多个订阅者的时候,他们各自的事件是独立的.
热流:无论有没有订阅者订阅,事件始终都会发生。当 热流有多个订阅者时,热流与订阅者们的关系是一对多的关系,可以与多个订阅者共享信息.
上面其实已经说得很清楚了,冷流和订阅者只能是一对一的关系,当我们要实现一个流,多个订阅者的需求时(这在开发中是很常见的),就需要热流了 从命名上也很容易理解,SharedFlow即共享的Flow,可以实现一对多关系,SharedFlow是一种热流 。
我们来看看SharedFlow的构造函数 。
其主要有3个参数 。
简单使用如下:
普通flow可使用shareIn扩展方法,转化成SharedFlow 。
shareIn主要也有三个参数:
started 接受以下的三个值
对于那些只执行一次的操作,您可以使用Lazily或者Eagerly。然而,如果您需要观察其他的流,就应该使用WhileSubscribed来实现细微但又重要的优化工作 。
WhileSubscribed策略会在没有收集器的情况下取消上游数据流,通过shareIn运算符创建的SharedFlow会把数据暴露给视图 (View),同时也会观察来自其他层级或者是上游应用的数据流.
让这些流持续活跃可能会引起不必要的资源浪费,例如一直通过从数据库连接、硬件传感器中读取数据等等。当您的应用转而在后台运行时,您应当保持克制并中止这些协程.
如上所示,它支持两个参数:
我们前面刚刚看了SharedFlow,为什么又冒出个StateFlow?
StateFlow 是 SharedFlow 的一个比较特殊的变种,StateFlow 与 LiveData是最接近的,因为
可以看出,StateFlow与LiveData是比较接近的,可以获取当前的值,可以想像之所以引入StateFlow就是为了替换LiveData 。
总结如下:
我们先来看看构造函数:
public fun MutableStateFlow(value: T): MutableStateFlow = StateFlowImpl(value ?: NULL) 。
与SharedFlow类似,我们也可以用stateIn将普通流转化成StateFlow 。
与shareIn类似,唯一不同的时需要传入一个默认值 同时之所以WhileSubscribed中传入了5000,是为了实现等待5秒后仍然没有订阅者存在就终止协程的功能,这个方法有以下功能 。
用户将您的应用转至后台运行,5 秒钟后所有来自其他层的数据更新会停止,这样可以节省电量。最新的数据仍然会被缓存,所以当用户切换回应用时,视图立即就可以得到数据进行渲染。订阅将被重启,新数据会填充进来,当数据可用时更新视图.
在屏幕旋转时,因为重新订阅的时间在5s内,因此上游流不会中止 。
与LiveData类似,我们也需要经常在页面中观察StateFlow 。
观察StateFlow需要在协程中,因此我们需要协程构建器,一般我们会使用下面几种 。
如上图所示:
这么说来,我们使用WhileSubscribed进行的配置岂不是无效了吗?订阅者一直存在,只有页面关闭时才会取消订阅 。
在某个特定的状态满足时启动协程,并且在生命周期所有者退出该状态时停止协程,如下图所示.
比如在某个Fragment的代码中
当这个Fragment处于STARTED状态时会开始收集流,并且在RESUMED状态时保持收集,最终在Fragment进入STOPPED状态时结束收集过程.
结合使用repeatOnLifecycle API和WhileSubscribed,可以帮助您的应用妥善利用设备资源的同时,发挥最佳性能 。
通过ViewModel暴露数据,并在页面中获取的最佳方式是
最佳实践如上图所示,如果采用其他方式,上游数据流会被一直保持活跃,导致资源浪费 当然,如果您并不需要使用到Kotlin Flow的强大功能,就用LiveData好了 :) 。
从上文其实可以看出,StateFlow与SharedFlow其实是挺像的,让人有些傻傻分不清,有时候也挺难选择该用哪个的 我们总结一下,它们的区别如下
对于新的订阅者,StateFlow只会重播当前最新值,SharedFlow可配置重播元素个数(默认为0,即不重播) 。
可以看出,StateFlow为我们做了一些默认的配置,在SharedFlow上添加了一些默认约束,这些配置可能并不符合我们的要求 。
StateFlow施加在SharedFlow上的约束可能不是最适合您,如果不需要访问myFlow.value,并且享受SharedFlow的灵活性,可以选择考虑使用SharedFlow 。
简单往往意味着不够强大,而强大又常常意味着复杂,两者往往不能兼得,软件开发过程中常常面临这种取舍.
LiveData的简单并不是它的缺点,而是它的特点。StateFlow与SharedFlow更加强大,但是学习成本也显著的更高.
我们应该根据自己的需求合理选择组件的使用 。
如果你的数据流比较简单,不需要进行线程切换与复杂的数据变换,LiveData对你来说相信已经足够了 如果你的数据流比较复杂,需要切换线程等操作,不需要发送重复值,需要获取myFlow.value,StateFlow对你来说是个好的选择 。
如果你的数据流比较复杂,同时不需要获取myFlow.value,需要配置新用户订阅重播无素的个数,或者需要发送重复的值,可以考虑使用SharedFlow 。
原文地址:https://juejin.cn/post/6986265488275800072 。
最后此篇关于官方推荐 Flow 取代 LiveData,有必要吗?的文章就讲到这里了,如果你想了解更多关于官方推荐 Flow 取代 LiveData,有必要吗?的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
今天上午据小米穿戴官方消息,为了保障更好的使用体验和更充足的备货,小米手表尊享版将延期至2020年2月开售。 据了解,早在今年11月初小米正式发布小米手表,共有标准版和尊享版两个版本,价格分别为1
我的意思是,如果我可以运行例如官方 docker 镜像 DEBIAN 并在此之上 运行具有相同支持架构的官方 docker 镜像 NGINX,例如Linux x86-64? 它会像我以非 docker
在 .NET 3.5 中,大量扩展方法被添加到核心代码库中。我注意到在 MSDN 中,IEnumerable<> 等添加了有关扩展方法的部分。 是否有已添加的所有扩展方法的列表以供引用? 编辑感谢您的
在vertx指南中,链接异步调用的顺序组合如下所示: FileSystem fs = vertx.fileSystem(); Future startFuture = Future.future();
neo4j 文档有 this page about creating unit tests for neo4j. 本质上它建议我们创建一个模拟数据库使用 graphDb = new TestGraph
我是 C++ 的新手,我想了解链接器是如何正式工作的。我正在使用 Linux Mint 16。是否存在 ld 链接器官方规范? 最佳答案 您可能会对链接器和共享库有更多了解 here还有here是 l
已关闭。此问题旨在寻求有关书籍、工具、软件库等的建议。不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以
我想创建一个自定义 Android 汽车应用程序,而不会分散驾驶员的注意力。我浏览了很多博客和网站,发现自 3.0 版本以来曾经有一些自定义应用程序被屏蔽。这些自定义应用程序的开发人员使用的是非官方的
我刚找到 this Project就像。嘿。为什么不尝试使用它呢? 所以。刚刚下载它(我没有做任何更改!),打开 Android Studio,运行它,然后遇到以下问题。 error: cannot
Docker 的官方 Postgres 镜像使用两个环境变量:POSTGRES_USER 和 POSTGRES_PASSWORD 参数化数据库创建: https://registry.hub.dock
我刚刚从 Python download page 下载了 Python 2.7.3 64 位安装程序我想验证签名。所以我需要导入 key ,我的首选方法是从受信任的 key 服务器获取它们。 Pyt
当我安装 Andoird 5.0 SDK 并导入 Camera2Basic 示例源代码时。CameraDevice.StateListener 和 CameraCaptureSession.State
在Design Philosophy节official Fragment guide ,它说: You should design each fragment as a modular and reu
我正在使用 Roslyn 编写一个应用程序来从语法和语义上分析 C# 源代码。对于正在分析的源代码中定义的每种类型,我想存储它是引用类型(类)、值类型(结构)还是接口(interface)。 类型的类
有没有官方的 XSLT 验证器,比如 http://validator.w3.org/用于 HTML 和 XHTML? 我知道http://validator.w3.org/也可用于验证 XML 和
我主要使用 C++ 进行科学计算,最近我一直将自己限制在一个非常类似于 C 的 C++ 特性子集;即,除了复杂和 STL 之外没有类/继承,模板仅用于查找/替换各种替换,以及其他一些我无法用语言表达的
我了解到Google会根据访问它的浏览器/设备来自动提供 TTF , EOT , WOFF 或 SVG 字体文件。 现在,我计划从服务器本身托管和提供字体文件,为此,我首先必须下载Web字体的所有文件
他们有什么不同? 例如,与官方 SDK 相比,选择 libfreenect 或 OpenNI+SensorKinect 有什么优势,反之亦然? 有什么缺点? 最佳答案 请注意,以下答案是按日期计算的,
我想使用官方的 Hashicorp 镜像来运行 Terraform 而不是手动安装。我已经关注了 dockerhub 上的文档,但没有关于如何在何处安装卷的任何详细信息 - 例如在当前目录中使用“ma
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 5 年前。
我是一名优秀的程序员,十分优秀!