Kotlin协程-ShareFlow

前言

replay粘性事件的个数,不同消费者订阅后,重新接收replay个之前的数据。

kotlin 复制代码
    fun main() {
        runBlocking {
            val flow = MutableSharedFlow<String>(replay = 1)
            // 第一个订阅
            launch {
                flow.collect{
                    println("collect1:$it")
                }
            }
            // 生产数据
            launch {
                (1..4).forEach{
                    println("emit:$it")
                    flow.emit("$it")
                }
            }
            //第二个订阅者 模拟在生产数据后才订阅
            launch {
                delay(1000)
                flow.collect{
                    println("collect2:$it")
                }
            }
        }
    }
}
输出:
emit:1
emit:2
collect1:1
collect1:2
emit:3
emit:4
collect1:3
collect1:4
collect2:4

replay=n时,多次订阅会将生产者的最后n次事件冲i性能发送一遍。

extraBufferCapacity

额外的缓存池。总的缓冲池extraBufferCapacity+replay个,用于生产速率>消费速率的情况。

kotlin 复制代码
fun main() {
    runBlocking {
        val flow = MutableSharedFlow<String>(replay = 2, extraBufferCapacity = 1)
        // 第一个订阅
        launch {
            flow.collect{
                delay(2000)
                println("collect1:$it")
            }
        }
        // 生产数据
        launch {
            (1..10).forEach{
                flow.emit("$it")
                println("emit:$it")
                delay(100)
            }
        }
    }
}
输出:
emit:1
emit:2
emit:3
emit:4
collect1:1
emit:5
collect1:2
emit:6
collect1:3
emit:7
collect1:4
emit:8
collect1:5
emit:9
collect1:6
emit:10
collect1:7
collect1:8
collect1:9
collect1:10

当缓存池满后,消费掉一个才会生产一个,生产者挂起。extraBufferCapacity=1时,发送和接收交替打印。当extraBufferCapacity>=7时,发送日志打印完毕后才开始打印接收日志。

onBufferOverFlow

缓冲策略,和Java线程池类似。线程池的拒绝策略。

kotlin 复制代码
public enum class BufferOverflow {
    //默认的,当生产速率大于消费速率并且缓冲池已满的情况,会挂起生产者,等待消费者
    SUSPEND,
    //丢弃老的数据
    DROP_OLDEST,
    //丢弃新的数据
    DROP_LATEST
}

StateFlow

StateFlow是一种特殊的ShareFlow。replay=1。必须要有初始值,不能为空,两次数据一致的情况下不会触发第二次。 LiveData相同点: 1、允许多个消费者订阅 2、粘性事件,事件数量=1 3、产生数据太快时都会丢失数据

StateFlow模式是BufferOverflow.DROP_OLDEST。Sharedflow是BufferOverflow.SUSPEND

不同点:

  1. StateFlow必须有默认值
  2. 默认是防抖,LiveData不防抖
  3. StateFlow没有和生命周期绑定

LiveData防抖可使用distinctUntilChanged。StateFlow没有生命周期绑定,可以利用Liecycle,在协程作用域内使用repeatOnLifecycle.

总结

  1. StateFlow是特殊的ShareFlow,replay=1 onBufferOverflow=BufferOverFlow.SUSPEND
  2. StateFlow可以替代LiveData使用
  3. StateFlow必须有默认值,默认防抖,有粘性事件,没有生命周期绑定
  4. ShareFlow没有默认值,粘性事件,可自定义事件数量,有缓冲池
  5. StateFlow表示状态,如View的显示和隐藏,按钮selectd都需要默认值
  6. ShareFlow是存储数据,例如列表list<T>数据,屏幕发生旋转,在Fragment的view消耗重建后的数据恢复
  7. 数据列表用ShareFlow<List<data>>,点赞或收藏数据的变化用StateFlow
相关推荐
Kapaseker1 分钟前
千锤百炼写View 摸爬滚打名声就
android·kotlin
虫小宝13 分钟前
微信群发消息API接口对接中Java后端的请求参数校验与异常反馈优化技巧
android·java·开发语言
三少爷的鞋17 分钟前
架构避坑:为什么 UseCase 不该启动协程,也不该切线程?
android
Mr -老鬼30 分钟前
Android studio 最新Gradle 8.13版本“坑点”解析与避坑指南
android·ide·android studio
xiaolizi5674899 小时前
安卓远程安卓(通过frp与adb远程)完全免费
android·远程工作
阿杰100019 小时前
ADB(Android Debug Bridge)是 Android SDK 核心调试工具,通过电脑与 Android 设备(手机、平板、嵌入式设备等)建立通信,对设备进行控制、文件传输、命令等操作。
android·adb
梨落秋霜9 小时前
Python入门篇【文件处理】
android·java·python
遥不可及zzz12 小时前
Android 接入UMP
android
Coder_Boy_14 小时前
基于SpringAI的在线考试系统设计总案-知识点管理模块详细设计
android·java·javascript
冬奇Lab14 小时前
【Kotlin系列03】控制流与函数:从if表达式到Lambda的进化之路
android·kotlin·编程语言