当前位置: 首页 > article >正文

kotlin中的flow使用,Flow跟生命周期结合

kotlin的Flow可以连续异步发出多个数据。

1. 普通flow,冷流类似于一个函数,当开始收集时才开始运行

val coldStream = flow {
        for (i in 1..5) {
            delay(100L)
            emit(i)
        }
    }
val collect1 = buildString {
    coldStream.collect { append(it).append(", ") }
}.removeSuffix(", ")
  • 在原来的的 CoroutineContext 中运行, 如果flow{}中运行完毕那流就结束了。
  • flow中的emit需在当前的上下文中调用,不可以切换到其它线程中发送;逻辑可以在其它Context执行,emit需要在当前上下文。
  • 监听者在collect()时是堵塞当前协程的,可以通过独立的上下文job保存,或者withTimeoutOrNull()的方式中途退出。

2. 把Callback转换为Flow流

val flow = callbackFlow<Long> {
    val dis = Observable.interval(200, TimeUnit.MILLISECONDS).subscribe {
        this.offer(it)
    }
    awaitClose {
        println("flow Closed.")
        dis.dispose()
    }
}

withTimeoutOrNull(5000) {
    flow.collect {
        println("Recv $it")
    }
}
  • awaitClose:当收集代码退出时也及时通知数据发送方停止。
  • 上面的offer()提示Deprecated, 但是改为trySend会报错,很奇怪。那就继续使用offer()吧。

3. SharedFlow热流,类似于 rxJava.PublishSubject 或者 LiveData。

val sharedFlow = MutableSharedFlow<Int>()
    scope.launch(Dispatchers.Default) {
        for (i in 1..10) {
            delay(200L)
            sharedFlow.emit(i)
            println("Emit: $i - ${threadName()}")
        }
    }
    scope.launch(Dispatchers.Default) {
        sharedFlow.collect {
            println("Col1: $it - ${threadName()}")
        }
    }

在UI中跟生命周期结合,由UI监听ViewModel的数据变动及时更新界面:

lifecycleScope.launch {
    viewModel.dataListFlow.flowWithLifecycle(lifecycle, Lifecycle.State.STARTED)
        .collect {
            adapter.datas = it
            adapter.notifyDataSetChanged()
        }
}
  • Channel也是有点类似,可以使用这个代替Channel的使用,还不用学习多一套接口。

4. StateFlow也是热流,能保留最后一个状态值,有数据防抖功能,相同数据不会真正发出。

val stateFlow = MutableSharedFlow<Int>()
// 启动一个 Job 来发射数据
val job = launch {
    repeat(100) { count ->
        delay(200) // 模拟一些工作
        val e = count/2*2
        println("Emit $e")
        stateFlow.emit(e) // 更新 StateFlow 的值
    }
}

// 订阅 StateFlow
val subscription = launch {
    stateFlow.collect { value ->
        println("StateFlow collect: $value")
        if (value >= 8) {
            println("Cancelling subscription...")
            cancel() // 取消收集
        }
    }
}

// 等待一段时间,确保 Job 运行
delay(1200)
job.cancelAndJoin() // 取消数据源的 Job
subscription.cancelAndJoin() // 取消收集的 Job
  • Compose中的UI状态很多都是使用 mutableStateOf() 就是这个 StateFlow()。

http://www.kler.cn/a/506439.html

相关文章:

  • AIGC时代 | 探索AI Agent的奥秘:四种设计模式引领未来智能趋势
  • springMVC实现文件上传
  • MYSQL创建表
  • (三)html2canvas将HTML 转为图片并实现下载
  • Termora跨平台 SSH/SFTP/Terminal 客户端工具
  • Linux 服务器挖矿木马防护实战:快速切断、清理与加固20250114
  • 大数据组件常用端口(hdfs端口、hive端口、yarn端口)
  • HTML5教程(中)
  • ubuntu20.04的虚拟机突然打不开terminal了
  • springweb项目练手附spring学习笔记链接
  • element-ui textarea备注 textarea 多行输入框
  • vue 纯前端导出 Excel
  • docker在不删除容器的情况下修改端口映射
  • PWM(Pulse Width Modulation,脉冲宽度调制)
  • 端口镜像和端口安全
  • 在Android Studio中如何实现contentprovider实验+SQLite数据库(保姆级教程)
  • 人工智能任务19-基于BERT、ELMO模型对诈骗信息文本进行识别与应用
  • 【Java】—— 基于Websocket实现页面聊天效果
  • 数据结构学习记录-数据结构概念
  • mysql 快速转为 sqlalchemy 模型 文件
  • 2.5G交换机 TL-SE2420 简单开箱评测,16个2.5G电口+4个10G光口(SFP+)
  • 《Compact Convolutional Transformers:开启计算机视觉新篇》
  • 2025最新版Sublime Text 4安装使用指南
  • WordPress 中将站点从绑定的域名迁移到使用 IP 地址
  • MySQL8.0新特性
  • 于灵动的变量变幻间:函数与计算逻辑的浪漫交织(上)