Android开发flow常见API的使用示例详解
作者:长安皈故里 时间:2021-09-25 05:27:49
collect通知flow执行
public suspend inline fun <T> Flow<T>.collect(crossinline action: suspend (value: T) -> Unit): Unit =
collect(object : FlowCollector<T> {
override suspend fun emit(value: T) = action(value)
})
flow是冷流,只有调用collect{}方法时才能触发flow代码块的执行。还有一点要注意,collect{}方法是个suspend声明的方法,需要在协程作用域的范围能调用。
除此之外,collect{}方法的参数是一个被crossinline修饰的函数类型,旨在加强内联,禁止在该函数类型中直接使用return关键字(return@标签除外)。
fun main() {
GlobalScope.launch {
flow {
emit("haha")
}.collect {
}
}
}
launchIn()指定协程作用域通知flow执行
public fun <T> Flow<T>.launchIn(scope: CoroutineScope): Job = scope.launch {
collect() // tail-call
}
这个方法允许我们直接传入一个协程作用域的参数,不需要直接在外部开启一个协程执行。本质上就是使用我们传入的协程作用域手动开启一个协程代码块调用collect{}通知协程执行。
这里看官方的源码有个tail-call的注释,也就是尾调用的意思,猜测这里可能官方会在这里进行了优化,减少了栈中方法调用的层级,降低栈溢出的风险。
fun main() {
flow {
emit("haha")
}.launchIn(GlobalScope)
}
catch{}捕捉异常
public fun <T> Flow<T>.catch(action: suspend FlowCollector<T>.(cause: Throwable) -> Unit): Flow<T> =
flow {
val exception = catchImpl(this)
if (exception != null) action(exception)
}
这个就是用来捕捉异常的,不过注意,只能捕捉catch()之前的异常,下面来个图阐述下:
即,只能捕捉第一个红框中的异常,而不能捕捉第二个红框中的异常。
merge()合流
public fun <T> merge(vararg flows: Flow<T>): Flow<T> = flows.asIterable().merge()
最终的实现类如下:
请注意,这个合流的每个流可以理解为是并行执行的,而不是后一个流等待前一个流中的flow代码块中的逻辑执行完毕再执行,这样做的目的可以提供合流的每个流的执行效果。
测试代码如下:
fun main() {
GlobalScope.launch {
merge(flow {
delay(1000)
emit(4)
}, flow {
println("flow2")
delay(2000)
emit(20)
}).collect {
println("collect value: $it")
}
}
}
输出日志如下:
map{}变换发送的数据类型
public inline fun <T, R> Flow<T>.map(crossinline transform: suspend (value: T) -> R): Flow<R> = transform { value ->
return@transform emit(transform(value))
}
这个api没什么可将的,很多的地方比如集合、livedata中都有它的影子,它的作用就是将当前数据类型变换成另一种数据类型(可以相同)。
fun main() {
GlobalScope.launch {
flow {
emit(5)
}.map {
"ha".repeat(it)
}.collect {
println("collect value: $it")
}
}
}
来源:https://juejin.cn/post/7134478501612093471
标签:Android,开发,flow,API
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Java 实战图书管理系统的实现流程
2023-12-19 05:11:13
![](https://img.aspxhome.com/file/2023/1/64541_0s.png)
C#使用LINQ查询操作符实例代码(一)
2021-11-27 01:41:57
![](https://img.aspxhome.com/file/2023/8/77258_0s.png)
Spring Boot Hello World的实现代码
2023-10-13 17:45:01
![](https://img.aspxhome.com/file/2023/4/84204_0s.jpg)
C#中括号强转、as、is区别详解
2023-05-07 03:04:45
![](https://img.aspxhome.com/file/2023/6/102256_0s.png)
C语言运用函数指针数组实现计算器功能
2023-10-01 18:45:25
详解如何实现SpringBoot的底层注解
2023-11-23 06:21:04
![](https://img.aspxhome.com/file/2023/0/59040_0s.png)
autojs模仿QQ长按弹窗菜单实现示例详解二
2022-10-20 07:04:37
![](https://img.aspxhome.com/file/2023/6/94956_0s.png)
RocketMQ实现随缘分BUG小功能示例详解
2023-01-20 04:21:05
![](https://img.aspxhome.com/file/2023/8/64038_0s.jpg)
详解Jackson 使用以及性能介绍
2023-02-21 00:08:31
![](https://img.aspxhome.com/file/2023/0/68570_0s.png)
java反射之通过反射了解集合泛型的本质(详解)
2023-02-04 03:10:25
![](https://img.aspxhome.com/file/2023/1/68151_0s.png)
MyBatis超详细讲解如何实现分页功能
2023-08-22 23:06:51
![](https://img.aspxhome.com/file/2023/6/58216_0s.png)
Java中StringUtils与CollectionUtils和ObjectUtil概念讲解
2023-11-29 07:45:38
![](https://img.aspxhome.com/file/2023/4/59004_0s.png)
C#设置与获取环境变量的方法详解
2021-09-03 20:55:29
C#创建自定义控件及添加自定义属性和事件使用实例详解
2022-05-30 02:10:12
![](https://img.aspxhome.com/file/2023/3/85653_0s.png)
android输入框与文本框加滚动条scrollview示例
2023-07-29 09:22:42
C#中委托、事件和回调的使用及说明
2023-08-13 01:00:24
![](https://img.aspxhome.com/file/2023/6/82136_0s.png)
java日志打印的完全使用指南
2023-07-02 15:02:28
![](https://img.aspxhome.com/file/2023/3/93063_0s.png)
Android recyclerview实现纵向虚线时间轴的示例代码
2023-08-23 07:03:39
![](https://img.aspxhome.com/file/2023/3/102613_0s.png)
MyBatis实现物理分页的实例
2023-03-13 04:21:45
C#中使用Join与GroupJoin将两个集合进行关联与分组
2023-11-11 23:40:47
![](https://img.aspxhome.com/file/2023/2/119522_0s.jpg)