Kotlin学习笔记(十三)Flow

Kotlin的Flow是一个基于协程的反应式编程工具,类似于RxJava但更简洁。Flow具有背压处理和生命周期感知能力,防止内存泄漏。文章介绍了Flow的关键操作符如map、filter、onEach等,以及如何处理背压问题。此外,还讨论了StateFlow和SharedFlow在替换LiveData中的应用,强调了Flow的冷流特性及其在多订阅者场景下的行为。
摘要由CSDN通过智能技术生成

Kotin的Flow,  就是Java的RxJava框架, 但是使用更加简洁。  结合协程的作用域,协程被取消时,Flow也会被取消,也能避免内存泄漏。

1. 引入库

    
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1"
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1'
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1"
    implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.5.1"
    implementation "androidx.activity:activity-ktx:1.6.1"
    implementation "androidx.fragment:fragment-ktx:1.5.5"

    implementation 'androidx.core:core-ktx:1.9.0'

前两项是协程库,因为Flow是构建在Kotlin协程基础之上的。第三项是用来提供协程作用域的。

后两项是ktx的扩展库,能帮我们简化不少代码的书写。最后一项是系统扩展的。

2. 普通操作符

掌握这些操作符基本够用了。

  • map

转换上流的数据,处理后,再向下发送给接收者。

  • filter

根据设定的条件,过滤掉上流的数据。

  • onEach

遍历每一条数据。通常用在调试查看中间状态值的。 上流初始数据,很可能在中流就被转换过了。用onEach就可以查看。

  • debounce

使得上流各项数据之间存在一定的时间间隔,不在时间间隔内就会删除上流过来的数据,不再下发给下流监听者。 时间点过于临近的数据只会保留最后一条。

  • sample

sample是采样的意思,在规定时间内读取上流的数据。当上流数据来的很快很频繁, 就是下流并不需要这么数据,只需展示少量数据的时候比较有用。 

  • reduce

累积上流的数据。它是一个终端操作符,就是和collect一样,是下流监听者。

flow.reduce { acc, value -> acc + value }
  • fold

和reduce操作符类似,也是一个终端操作符。区别在于,fold需要传入一个初始值,这个初始值会作为首个累积值被传递到fold的函数体当中,它的公式如下:

flow.fold(initial) { acc, value -> acc + value }

3.合并操作符 

  • flatMapConcat

 flatMap有三个操作符。它们是用来转换上流的。和map不同的地方是, map是转换上流的数据,而 flatMap是把上流给转换了。把老的flow换成了新的flow, 数据和数据类型肯定也变了。

flatMapConcat就是典型的。flatMapConcat能保证上流数据的顺序,相当于单线程处理数据, 上流发一个,flatMapConcat处理一个。

  • flatMapMerge

和flatMapConcat不同,flatMapConcat能保证上流数据的顺序,相当于单线程处理数据。但是flatMapMerge的内部是启用多线程并发来进行数据处理的,它不会保证最终结果的顺序。

  • flatMapLatest

flow1中的数据传递到flow2中会立刻进行处理,但如果flow1中的下一个数据要发送了,而flow2中上一个数据还没处理完,则会直接将剩余逻辑取消掉,开始处理最新的数据。

  • zip

也就是多个上流flow,合并成一个上流flow。而且多个上流flow,它们之间是并行运行的。同时发出。当个数一样的时候,等少了上流flow发完时,就结束了。其他上流flow的数据就舍弃了。

4.背压操作符

如果上流的流速大于下流处理数据的速度,并且不均匀问题持续放大。这就是背压问题。下面是处理背压的操作符。

  • buffer

buffer操作符可以释放上流产能。

collect函数中的数据处理是会对flow函数中的数据发送产生影响的。因为默认情况下,collect函数和flow函数会运行在同一个协程当中,因此collect函数中的代码没有执行完,flow函数中的代码也会被挂起等待。

也就是说,我们在collect函数中处理数据需要花费1秒,flow函数同样就要等待1秒。collect函数处理完成数据之后,flow函数恢复运行

那能不能,上流发上流的, 下流处理下流的,各自独立呢? 也行的,就是用buffer操作符。 上流发过来的数据先存在buffer中, 下流有时间处理的时候就去拿。

  • collectLatest

当有新数据到来时而前一个数据还没有处理完,则会将collectLastest中前一个数据剩余的处理逻辑全部取消。马上去处理新的数据。很喜新厌旧。

  • conflate

和collectLastest不同, conflate会保持collect中的处理逻辑完整性。

5. StateFlow和SharedFlow

StateFlow和SharedFlow可以替换LiveData。StateFlow具有粘性,SharedFlow默认不具有粘性,当也可以变成有粘性。使用flow构建函数构建出的Flow是属于冷流,也就是在没有任何接受端的情况下,Flow是不会工作的

我们知道Flow的特点之一就是冷流。当数据被订阅的时候,发布者才开始执行发射数据流的代码。并且当有多个订阅者的时候,每一个订阅者和发布者都是一对一的关系,每个订阅者都会收到发布者完整的数据。

引用:

Kotlin Flow响应式编程,StateFlow和SharedFlow

Kotlin Flow响应式编程,操作符函数进阶

Kotlin Flow响应式编程,基础知识入门

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值