Kotlin中的StateFlow和SharedFlow有什么区别?

2024-06-06 06:36

本文主要是介绍Kotlin中的StateFlow和SharedFlow有什么区别?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点

在Kotlin的协程库kotlinx.coroutines中,StateFlowSharedFlow是两种用于处理事件流的API,它们有相似之处,但在设计上的初衷和内在机制上有明显区别。

这次我们就对StateFlowSharedFlow进行深入对比:

StateFlowSharedFlow 概述
  • StateFlow

    • 一种用于持有单一最新状态值并发射给多个观察者的热流。适合用于状态管理场景,例如表示UI状态。
    • 和livedata比较像,有新数据可以通知collect的一方
    • 同时又具有flow的所有特点,比如可以挂起,切换线程
  • SharedFlow

    • 一种通用热流,可以发射事件流而不是仅限于持有最新状态。适合处理事件总线、观察者模式等场景。
    • 也就是一对多的关系,可以有多个collector
    • 同时又具有flow的所有特点,比如可以挂起,切换线程
    • 和上面的StateFlow不同的是,这个不能主动通知collect方,需要不断emit元素,也就是利用了flow的功能

设计初衷不同

  • StateFlow的设计是为了取代ConflatedBroadcastChannel,用于表示状态,并且总是持有最新的状态值。
  • SharedFlow的设计是为了提供一个通用的、可共享的事件流机制,支持事件的重播、缓存等。

状态持有和重播不同

  • StateFlow

    • 总是持有最新的状态值。
    • 新的观察者会立即收到当前持有的状态值。
    • 流中的每个新值都会覆盖之前的值,即只有最新的状态值会被保留。
  • SharedFlow

    • 不会持有单一最新状态值(除非配置了重播缓存)。
    • 可以配置重播机制(replay 参数)以指定新的观察者接收之前多少个已发射的值。
    • 可以配置不同的缓冲策略,如BufferOverflow来定制事件丢弃策略。

类型层次结构

  • StateFlow继承自SharedFlow,所以它是SharedFlow的一种特化实现。
public interface StateFlow<out T> : SharedFlow<T> {/*** The current value of this state flow.*/public val value: T
}

应用场景

  • StateFlow:适用于状态管理场景,例如在ViewModel中表示UI状态。因为它始终持有最新的状态,能确保观察者总能获得最新的状态。

  • SharedFlow:更加灵活和通用,适用于事件处理、事件总线、消息队列等场景。尤其适合需要重播特定数量的历史事件或者处理事件丢弃政策的场景。

使用对比

StateFlow 使用示例
val _stateFlow = MutableStateFlow<Int>(0) // Initial state
val stateFlow: StateFlow<Int> = _stateFlow// Collect values
stateFlow.collect { value ->println("StateFlow value: $value")
}// Emit new state
_stateFlow.value = 1
SharedFlow 使用示例
val _sharedFlow = MutableSharedFlow<Int>(replay = 2) // Buffer size of 2
val sharedFlow: SharedFlow<Int> = _sharedFlow// Collect values
sharedFlow.collect { value ->println("SharedFlow value: $value")
}// Emit new values
_sharedFlow.emit(1)
_sharedFlow.emit(2)
_sharedFlow.emit(3)

重要的API

StateFlow
  • value:获取或设置当前的状态值。
  • collect:收集状态值的变化。
SharedFlow
  • emit:发射一个新事件。
  • collect:收集事件。
  • replayCache:获取重播缓存。

此外,两者还有collectLatest接口,下次我们再来详细对比看看

选择指南

  • 选择StateFlow:如果你的应用场景需要在多个观察者之间共享最新的状态,并且没有兴趣保留状态的历史记录,那么StateFlow是你的最佳选择。
  • 选择SharedFlow:如果你需要一个更通用的事件流机制,并且可能需要缓存和重播事件,SharedFlow提供了更强的灵活性和定制性。

对于StateFlowSharedFlow,你有什么经验和看法?欢迎留言区讨论


欢迎关注我的公众号查看更多精彩文章!

AntDream

这篇关于Kotlin中的StateFlow和SharedFlow有什么区别?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1035353

相关文章

MySQL 筛选条件放 ON后 vs 放 WHERE 后的区别解析

《MySQL筛选条件放ON后vs放WHERE后的区别解析》文章解释了在MySQL中,将筛选条件放在ON和WHERE中的区别,文章通过几个场景说明了ON和WHERE的区别,并总结了ON用于关... 今天我们来讲讲数据库筛选条件放 ON 后和放 WHERE 后的区别。ON 决定如何 "连接" 表,WHERE

Mybatis的mapper文件中#和$的区别示例解析

《Mybatis的mapper文件中#和$的区别示例解析》MyBatis的mapper文件中,#{}和${}是两种参数占位符,核心差异在于参数解析方式、SQL注入风险、适用场景,以下从底层原理、使用场... 目录MyBATis 中 mapper 文件里 #{} 与 ${} 的核心区别一、核心区别对比表二、底

Spring Boot Interceptor的原理、配置、顺序控制及与Filter的关键区别对比分析

《SpringBootInterceptor的原理、配置、顺序控制及与Filter的关键区别对比分析》本文主要介绍了SpringBoot中的拦截器(Interceptor)及其与过滤器(Filt... 目录前言一、核心功能二、拦截器的实现2.1 定义自定义拦截器2.2 注册拦截器三、多拦截器的执行顺序四、过

C# Semaphore与SemaphoreSlim区别小结

《C#Semaphore与SemaphoreSlim区别小结》本文主要介绍了C#Semaphore与SemaphoreSlim区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录一、核心区别概览二、详细对比说明1.跨进程支持2.异步支持(关键区别!)3.性能差异4.API 差

Java中自旋锁与CAS机制的深层关系与区别

《Java中自旋锁与CAS机制的深层关系与区别》CAS算法即比较并替换,是一种实现并发编程时常用到的算法,Java并发包中的很多类都使用了CAS算法,:本文主要介绍Java中自旋锁与CAS机制深层... 目录1. 引言2. 比较并交换 (Compare-and-Swap, CAS) 核心原理2.1 CAS

MySQL中VARCHAR和TEXT的区别小结

《MySQL中VARCHAR和TEXT的区别小结》MySQL中VARCHAR和TEXT用于存储字符串,VARCHAR可变长度存储在行内,适合短文本;TEXT存储在溢出页,适合大文本,下面就来具体的了解... 目录一、VARCHAR 和 TEXT 基本介绍1. VARCHAR2. TEXT二、VARCHAR

Kotlin 协程之Channel的概念和基本使用详解

《Kotlin协程之Channel的概念和基本使用详解》文章介绍协程在复杂场景中使用Channel进行数据传递与控制,涵盖创建参数、缓冲策略、操作方式及异常处理,适用于持续数据流、多协程协作等,需注... 目录前言launch / async 适合的场景Channel 的概念和基本使用概念Channel 的

python中getsizeof和asizeof的区别小结

《python中getsizeof和asizeof的区别小结》本文详细的介绍了getsizeof和asizeof的区别,这两个函数都用于获取对象的内存占用大小,它们来自不同的库,下面就来详细的介绍一下... 目录sys.getsizeof (python 内置)pympler.asizeof.asizeof

Vue和React受控组件的区别小结

《Vue和React受控组件的区别小结》本文主要介绍了Vue和React受控组件的区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录背景React 的实现vue3 的实现写法一:直接修改事件参数写法二:通过ref引用 DOMVu

Go之errors.New和fmt.Errorf 的区别小结

《Go之errors.New和fmt.Errorf的区别小结》本文主要介绍了Go之errors.New和fmt.Errorf的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考... 目录error的基本用法1. 获取错误信息2. 在条件判断中使用基本区别1.函数签名2.使用场景详细对