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

server/2025/1/17 17:45:35/

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

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

kotlin">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流

kotlin">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。

kotlin">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的数据变动及时更新界面:

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

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

kotlin">val stateFlow = MutableSharedFlow<Int>()
// 启动一个 Job 来发射数据
val job = launch {repeat(100) { count ->delay(200) // 模拟一些工作val e = count/2*2println("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.ppmy.cn/server/159148.html

相关文章

WPS excel使用宏编辑器合并 Sheet工作表

使用excel自带的工具合并Sheet表&#xff0c;我们会发现需要开通WPS会员才能使用合并功能&#xff1b; 那么WPS excel如何使用宏编辑器进行合并 Sheet表呢&#xff1f; 1、首先我们要看excel后缀是 .xlsx 还是 .xls &#xff1b;如果是.xlsx 那么 我们需要修改为 .xls 注…

Windows远程桌面网关出现重大漏洞

微软披露了其Windows远程桌面网关&#xff08;RD Gateway&#xff09;中的一个重大漏洞&#xff0c;该漏洞可能允许攻击者利用竞争条件&#xff0c;导致拒绝服务&#xff08;DoS&#xff09;攻击。该漏洞被标识为CVE-2025-21225&#xff0c;已在2025年1月的补丁星期二更新中得到…

为什么npm i 要加上--save-dev

在 npm 中&#xff0c;--save-dev 是一个标志&#xff0c;用于将依赖项安装为开发依赖。这些依赖项通常是开发过程中需要使用的工具或库&#xff0c;而不是在生产环境中运行代码时需要的依赖。 开发依赖&#xff08;DevDependencies&#xff09; 当你在项目中使用 npm install…

TouchGFX学习笔记(一)

配置请参考链接&#xff1a;TouchGFX超低配置移植教程-CSDN博客 一&#xff0c;显示配置 1.适当增加堆栈大小 2.适当增大缓冲大小 双重缓冲消除了任何撕裂的风险&#xff0c;无论渲染下一帧需要多长时间&#xff0c;因为TfT控制器&#xff0c;例如&#xff0c;总是可以访问最…

Sprint Boot教程之五十八:动态启动/停止 Kafka 监听器

Spring Boot – 动态启动/停止 Kafka 监听器 当 Spring Boot 应用程序启动时&#xff0c;Kafka Listener 的默认行为是开始监听某个主题。但是&#xff0c;有些情况下我们不想在应用程序启动后立即启动它。 要动态启动或停止 Kafka Listener&#xff0c;我们需要三种主要方法…

Android-目前最稳定和高效的UI适配方案

谈到适配&#xff0c;首先需要介绍几个基本单位&#xff1a; 1、密度无关像素&#xff08;dp&#xff09;&#xff1a; 含义&#xff1a;density-independent pixel&#xff0c;叫dp或dip&#xff0c;与终端上的实际物理像素点无关 单位&#xff1a;dp&#xff0c;可以保证在…

基于多个边缘盒子部署的综合视频安防系统的智慧地产开源了

智慧地产视觉监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒&#xff0c;省去繁琐重复的适配流程&#xff0c;实现芯片、算法、应用的全流程组合&#xff0c;从而大大减少企业级应用约95%的开发成本。 AI是新形势下数…

HTML5+Canvas实现的鼠标跟随自定义发光线条源码

源码介绍 HTML5Canvas实现的鼠标跟随自定义发光线条特效源码非常炫酷&#xff0c;在黑色的背景中&#xff0c;鼠标滑过即产生彩色变换的发光线条效果&#xff0c;且线条周围散发出火花飞射四溅的粒子光点特效。 效果预览 源码如下 <!DOCTYPE html PUBLIC "-//W3C//D…