Kotlin:用源码来深入理解 ‘StateFlow和SharedFlow的区别和联系‘

Kotlin:用源码来深入理解 ‘StateFlow和SharedFlow的区别和联系’

在这里插入图片描述

在这篇文章中,我们将深入研究Kotlin中的StateFlow和SharedFlow,以及它们的相似之处和不同之处。我们将通过查看它们的源代码来理解它们的工作原理,这将帮助我们更好地理解它们的用途和优势。

StateFlow

StateFlow是Kotlin中的一个概念,它是一个热Flow,可以存储状态。它的主要特点是始终保持最新的状态值,而且任何时候都可以访问这个状态值。当你观察StateFlow时,你将首先接收到当前的状态值,然后每当状态改变时,你都会收到新的状态值。

StateFlow的源代码如下:
伪源码:

public abstract class StateFlow<out T> : Flow<T> {
    public abstract val value: T
    public abstract val replayCache: List<T>
}

在这段代码中,我们可以看到StateFlow有一个value属性,这是当前的状态值。还有一个replayCache属性,它是一个包含最近发出的值的列表。在StateFlow的情况下,这个列表总是包含一个元素,即当前的状态值。

当然实际上的源码是继承自SharedFlow, 但是因为SharedFlow中有个public abstract val replayCache: List<T> 所以就相当于上面的伪源码
实际上的源码:

public interface StateFlow<out T> : SharedFlow<T> {
    /**
     * The current value of this state flow.
     */
    public val value: T
}

SharedFlow

SharedFlow也是一个热Flow,但它和StateFlow有一些关键的区别。首先,SharedFlow没有一个固定的当前值。相反,它只是广播它接收到的所有值。其次,SharedFlow可以有一个回放缓存,它是一个包含最近发出的值的列表。这个列表的大小可以在创建SharedFlow时设置。

SharedFlow的源代码如下:

public abstract class SharedFlow<out T> : Flow<T> {
    public abstract val replayCache: List<T>
}

在这段代码中,我们可以看到SharedFlow只有一个replayCache属性,没有value属性。这反映了SharedFlow和StateFlow的主要区别:SharedFlow没有一个固定的当前值,而StateFlow有。

StateFlow和SharedFlow的联系和区别

StateFlow和SharedFlow都是热Flow,它们都可以广播值给多个观察者。然而,它们在如何处理这些值方面有一些关键的区别。StateFlow始终有一个当前值,而SharedFlow没有。相反,SharedFlow只是广播它接收到的所有值。

另一方面,SharedFlow可以有一个回放缓存,这是一个包含最近发出的值的列表。这个列表的大小可以在创建SharedFlow时设置。而StateFlow的回放缓存总是只包含当前的状态值。

StateFlow的使用示例

让我们看一个StateFlow的使用示例。在这个例子中,我们有一个名为uiState的StateFlow,它保存了UI的状态。

private val _uiState = MutableStateFlow(UiState())
val uiState: StateFlow<UiState> = _uiState

在这个例子中,我们首先创建了一个MutableStateFlow,它是一个可以改变的StateFlow。然后,我们创建了一个只读的StateFlow,它的值是MutableStateFlow的值。这样,我们可以在内部改变_uiState的值,但外部只能观察uiState的值。

SharedFlow的使用示例

现在让我们看一个SharedFlow的使用示例。在这个例子中,我们有一个名为events的SharedFlow,它用于发送事件。

private val _events = MutableSharedFlow<Event>()
val events: SharedFlow<Event> = _events

在这个例子中,我们首先创建了一个MutableSharedFlow,它是一个可以改变的SharedFlow。然后,我们创建了一个只读的SharedFlow,它的值是MutableSharedFlow的值。这样,我们可以在内部发送事件到_events,但外部只能观察events

StateFlow和SharedFlow的比较

从这两个例子中,我们可以看出StateFlow和SharedFlow的一些关键区别。StateFlow有一个固定的当前值,这个值可以被观察者获取。这使得StateFlow非常适合用于表示状态,如UI状态。

另一方面,SharedFlow没有固定的当前值。相反,它只是广播它接收到的所有值。这使得SharedFlow非常适合用于表示事件,如用户操作。

复杂的StateFlow示例

在这个例子中,我们有一个名为uiState的StateFlow,它保存了UI的状态。我们还有一个名为loadData的函数,它从网络加载数据,并更新uiState

private val _uiState = MutableStateFlow(UiState())
val uiState: StateFlow<UiState> = _uiState

suspend fun loadData() {
    _uiState.value = UiState.Loading
    val data = repository.loadData()
    _uiState.value = UiState.Success(data)
}

在这个例子中,loadData函数首先将uiState的值设置为Loading,然后加载数据,最后将uiState的值设置为Success。这样,观察者可以观察到uiState的变化,并根据其值来更新UI。

复杂的SharedFlow示例

在这个例子中,我们有一个名为events的SharedFlow,它用于发送事件。我们还有一个名为sendEvent的函数,它发送一个事件到events

private val _events = MutableSharedFlow<Event>()
val events: SharedFlow<Event> = _events

suspend fun sendEvent(event: Event) {
    _events.emit(event)
}

在这个例子中,sendEvent函数发送一个事件到events。观察者可以观察到events,并根据接收到的事件来执行相应的操作。

StateFlowSharedFlow的比较

从这两个例子中,我们可以看到StateFlow和SharedFlow在复杂场景下的使用。StateFlow非常适合用于表示可以随时间变化的状态,如UI状态。SharedFlow则非常适合用于表示一次性的事件,如用户操作。

StateFlow和SharedFlow的区别

StateFlow和SharedFlow虽然都是Flow,但它们有一些关键的区别。

  • StateFlow有一个固定的当前值,这个值可以被观察者获取。这使得StateFlow非常适合用于表示状态,如UI状态。

  • SharedFlow没有固定的当前值。相反,它只是广播它接收到的所有值。这使得SharedFlow非常适合用于表示事件,如用户操作。

StateFlow和SharedFlow的使用建议

在选择使用StateFlow还是SharedFlow时,你应该根据你的需求来决定。

  • 如果你需要表示一个可以随时间变化的状态,你应该使用StateFlow。例如,你可以使用StateFlow来表示UI的状态。

  • 如果你需要表示一次性的事件,你应该使用SharedFlow。例如,你可以使用SharedFlow来表示用户操作。

这就是我们对StateFlow和SharedFlow的深入理解。希望这篇文章能帮助你更好地理解和使用Kotlin的Flow。

举例说明

在我们的应用中,我们有一个购物车功能。购物车的内容是一个状态,它随着用户添加或删除商品而变化。我们可以使用StateFlow来表示这个状态。

private val _cart = MutableStateFlow<List<Product>>(emptyList())
val cart: StateFlow<List<Product>> = _cart

suspend fun addProduct(product: Product) {
   _cart.value = _cart.value + product
}

suspend fun removeProduct(product: Product) {
   _cart.value = _cart.value - product
}

在这个例子中,我们有一个名为cart的StateFlow,它表示购物车的内容。我们还有两个函数addProductremoveProduct,它们分别用于添加商品到购物车和从购物车中删除商品。

另一方面,我们的应用还有一个消息通知功能。当有新消息时,我们需要通知所有的观察者。我们可以使用SharedFlow来实现这个功能。

private val _messages = MutableSharedFlow<Message>()
val messages: SharedFlow<Message> = _messages

suspend fun sendMessage(message: Message) {
    _messages.emit(message)
}

在这个例子中,我们有一个名为messages的SharedFlow,它用于发送消息。我们还有一个名为sendMessage的函数,它用于发送消息到messages

这就是我们在实际应用中如何使用StateFlow和SharedFlow的例子。希望这些例子能帮助你更好地理解StateFlow和SharedFlow的用途。

感谢阅读, Best Regards!

免责声明

  1. 本文内容及信息,部分或全部可能经由人工智能技术协助编写或完全由AI生成。我已尽力确保这些生成内容的准确性和合法性,然而鉴于人工智能技术固有的局限性,仍可能出现不准确陈述、错误信息或与其他来源相似的内容。

  2. 对于任何读者在阅读过程中发现的问题,包括但不限于涉嫌抄袭、不实或误导性的信息,请及时私信我进行反馈,我会尽快对相关问题进行核实,并作出必要的修正或删除。

  3. 在此明确声明,我所提供的所有可能涉及AI生成的文章和信息,其目的在于知识分享、学习探讨及提供参考,并不能代表我个人在每项具体观点上的详尽研究、深度分析或直接推荐。读者在采纳、引用或应用其中的观点时,应当结合实际情况与其它可靠资料进行独立判断,并自行承担相应责任。

  4. 敬请各位读者,在将我发布的AI生成内容作为决策依据时,充分认识到潜在的局限性,并对此类信息进行进一步的验证和核实。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/360831.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大数据 - Spark系列《二》- 关于Spark在Idea中的一些常用配置

上一篇&#xff1a; 大数据 - Spark系列《一》- 从Hadoop到Spark&#xff1a;大数据计算引擎的演进-CSDN博客 目录 1. &#x1f959;Idea中配置Live Templates来快速生成代码片段 2. &#x1f959;Idea中配置文件模板自定义初始代码 3.&#x1f959;设置spark-submit提交程…

刨析数据结构(一)

&#x1f308;个人主页&#xff1a;小田爱学编程 &#x1f525; 系列专栏&#xff1a;数据结构————"带你无脑刨析" &#x1f3c6;&#x1f3c6;关注博主&#xff0c;随时获取更多关于数据结构的优质内容&#xff01;&#x1f3c6;&#x1f3c6; &#x1f600;欢迎…

chromedriver安装和环境变量配置

chromedriver 1、安装2、【重点】环境变量配置&#xff08;1&#xff09;包的复制&#xff1a;&#xff08;2&#xff09;系统环境变量配置 3、验证 1、安装 网上随便搜一篇chromedriver的安装文档即可。这里是一个快速链接 特别提醒&#xff1a;截止2024.1.30&#xff0c;chr…

计算机网络_1.3电路交换、分组交换和报文交换

1.3电路交换、分组交换和报文交换 一、电路交换1、“电路交换”例子引入2、电路交换的三个阶段3、计算机之间的数据传送不适合采用电路交换 二、分组交换1、发送方&#xff08;1&#xff09;报文&#xff08;2&#xff09;分组&#xff08;3&#xff09;首部 2、交换节点3、接收…

酒店|酒店管理小程序|基于微信小程序的酒店管理系统设计与实现(源码+数据库+文档)

酒店管理小程序目录 目录 基于微信小程序的酒店管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员模块的实现 (1) 用户信息管理 (2) 酒店管理员管理 (3) 房间信息管理 2、小程序序会员模块的实现 &#xff08;1&#xff09;系统首页 &#xff0…

【fabrc.js】 创建组(fabric.Group)类型的 3 种方式

方法1&#xff1a;先选中已存在画布内多个图形&#xff0c;然后拿到ActiveSelection数据&#xff0c;随后调用 toGroup() 即可将选中的图形创建为组对象&#xff1b;方法2&#xff1a;new fabric.Group() 获取group实例&#xff0c;通过new的时候传入图形参数[o1,o2...]&#x…

【代码能力提升 | 代码阅读学习】分析 VoxelNet 的 主干

文章目录 前言代码分析VoxelNet model2.数据处理2.1单个样本处理2.2处理成batch 最后&#xff0c;附上我一步步调试代码&#xff0c;到3D-conv 前言 代码来自&#xff1a;https://github.com/skyhehe123/VoxelNet-pytorch 其中 测试数据来自&#xff1a;https://github.com/ga…

python爬虫之豆瓣首页图片爬取

网址&#xff1a;https://movie.douban.com/ import requests from lxml import etree import re url https://movie.douban.com headers {User-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.289 Safari/5…

CGAL5.4.1 边塌陷算法

目录 1、使用曲面网格的示例 2、使用默认多面体的示例 3、使用丰富多面体的示例 主要对1、使用曲面网格的示例 进行深度研究 CGAL编译与安装CGAL安装到验证到深入_cgal测试代码-CSDN博客 参考资料CGAL 5.4.5 - Triangulated Surface Mesh Simplification: User Manual …

卡片式 UI 设计的 8 个秘诀,让你轻松打造高颜值界面

做卡片设计最重要的是什么&#xff1f;我将在这篇文章中分享 8 最关键的细节。在此之前&#xff0c;让我们一起来对付一下。 UI 梳理卡片设计的基础&#xff0c;总结哪些场景适合卡片设计。 卡片是 UI 其中一个组件元素可以创建一个清晰的视觉单元&#xff0c;使信息更具逻辑性…

expect 语言 Here Document 多行重定向

一、expect是什么 1.1 expect定义 是建立在tcl&#xff08;tool command language&#xff09;语言基础上的一个工具&#xff0c;常被用于进行自动化控制和测试&#xff0c;解决shell脚本中交互的相关问题 1.2 怎么安装expect yum install -y expect 进行安装 二、怎么使用e…

力扣hot100 电话号码的字母组合 回溯

Problem: 17. 电话号码的字母组合 文章目录 思路复杂度&#x1f49d; Code 思路 &#x1f468;‍&#x1f3eb; 参考题解 复杂度 时间复杂度: O ( 3 8 ) O(3^8) O(38) 空间复杂度: O ( 3 8 ) O(3^8) O(38) &#x1f49d; Code class Solution {String[] map { "…

实战项目(二)汽车保养管家系统

一、实现技术 前端技术&#xff1a;html、javascript(jquery、ajax、json)、css、layui 后端技术&#xff1a;java、mysql、servlet 开发工具&#xff1a;eclipse、vscode 二、项目描述 基于web的汽车保养管家系统的设计与实现 一、功能需求 1&#xff0e;用户功能 1.1…

《Pandas 简易速速上手小册》第1章:Pandas入门(2024 最新版)

文章目录 1.1 Pandas 简介1.1.1 基础知识1.1.2 案例&#xff1a;气候变化数据分析1.1.3 拓展案例一&#xff1a;金融市场分析1.1.4 拓展案例二&#xff1a;社交媒体情感分析 1.2 安装和配置 Pandas1.2.1 基础知识1.2.2 案例&#xff1a;个人财务管理1.2.3 拓展案例一&#xff1…

力扣 55.跳跃游戏

思路&#xff1a; 从后往前遍历&#xff0c;遇到元素为0时&#xff0c;记录对应的下标位置&#xff0c;再向前遍历元素&#xff0c;看最大的跳跃步数能否跳过0的位置&#xff0c;不能则继续往前遍历 代码&#xff1a; class Solution { public:bool canJump(vector<int>…

ip https证书多少钱

IP https证书是一种数字证书&#xff0c;用于在网络传输中保护数据的机密性和完整性。它通过使用SSL&#xff08;安全套接层&#xff09;协议&#xff0c;在客户端和服务器之间建立一条加密通道&#xff0c;确保数据在传输过程中不会被窃取或篡改。而IP https证书的价格和它的品…

基于springboot的视频点播系统

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

5G智慧钢铁厂数字孪生三维可视化,推进钢铁新型工业化数字化转型

5G智慧钢铁厂数字孪生三维可视化&#xff0c;推进钢铁新型工业化数字化转型。随着科技的不断发展&#xff0c;数字化转型已经成为钢铁企业转型升级的必经之路。而5G技术的广泛应用&#xff0c;为钢铁企业数字化转型提供了新的机遇。其中&#xff0c;5G智慧钢铁厂数字孪生三维可…

SpringCloud_学习笔记_1

SpringCloud01 1.认识微服务 随着互联网行业的发展&#xff0c;对服务的要求也越来越高&#xff0c;服务架构也从单体架构逐渐演变为现在流行的微服务架构。这些架构之间有怎样的差别呢&#xff1f; 1.0.学习目标 了解微服务架构的优缺点 1.1.单体架构 单体架构&#xff…

Android Studio 安装配置教程 - Windows版

Android Studio下载 安装&#xff1a; 下载&#xff1a; Android Studio Hedgehog | 2023.1.1 | Android Developers (google.cn) 安装&#xff1a; 基本不需要思考跟着走 默认下一步 默认下一步 自定义修改路径&#xff0c;下一步 默认下一步&#xff0c;不勾选 默认下一…