Android开发flow常见API的使用示例详解
作者:长安皈故里 发布时间:2021-09-25 05:27:49
标签:Android,开发,flow,API
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


猜你喜欢
- 1.官网下载JDK:1.1下载地址:https://www.oracle.com/java/technologies/javase-down
- Java的最基本的同步方式,即使用synchronized关键字来控制一个方法的并发访问。 每一个用synchronized关键字声明的方法
- @ConfigurationProperties实现类型安全的配置问题描述从之前@Value的使用,可以知道@Value可以灵活的把配置文件
- 1、Android内存管理机制1.1 Java内存分配模型先上一张JVM将内存划分区域的图程序计数器:存储当前线程执行目标方法执行到第几行。
- 背景在接口请求过程中,传递json对象,springboot转换为实体VO对象后,所有属性都为null。post请求:后台接收请求:当时就懵
- 之前已经为大家介绍过利用Java实现带GUI的气泡诗词特效,本文将为大家介绍另一种方法同样也可以实现气泡诗词的效果。下面是示例代码impor
- 1.项目简绍本项目使用SpringBoot开发,jdbc5.1.48 Mybatis 源码可下载其中涉及功能有:Mybatis的使用,Thy
- SpringBoot配置文件优先级前面SpringBoot基础有提到,关于SpringBoot配置文件可以是properties或者是yam
- Stream流常见的中间操作方法Streamfilter(Predicate predicate):用于对流中的数据进行过滤predicat
- 本文实例为大家分享了Android开发之ViewPager实现滑动切换页面的具体代码,供大家参考,具体内容如下基本构件activity_ma
- 本文实例为大家分享了Android实现记事本功能的具体代码,供大家参考,具体内容如下MainActivity.java代码:package
- 如何使用union多表分页条件查询当前项目有一个全局搜索的功能,需要涉及到7-8张主表,由于当前项目使用的是Jpa,所以我决定使用原生sql
- 现在看我文章的多数是一些老Android了,相信每个人使用起LayoutInflater都是家常便饭,信手拈来。但即使是这样,我仍然觉得这个
- IntelliJ IDEA一个吸引人的地方在于,他有比较好的反编译工具,这让Eclipse用户牙痒痒。但不要紧,本文介绍如何在Eclipse
- PagerBottomTabStrip 是一个基本按谷歌Material Design规范完成的安卓底部导航栏控件官方设计规范:https:
- Android选择图片的两种方式:第一种:单张选取通过隐式启动activity,跳转到相册选择一张返回结果关键代码如下:发送请求:priva
- Java:对象创建和初始化过程1.Java中的数据类型 Java中有3个数据类型:基本数据类型(在Jav
- 在使用AndroidNDK开发的时候有个事情是很烦人的,那就是创建本地代码文件夹,生成本地代码文件和创建本地代码的编译文件。特别是实现本地方
- 自己写的一个日历记事本效果图 具体步骤:1.添加控件SkinEngine。 1.右键“工具箱”。“添加选项卡”,取名“皮肤”。
- 前言在一个高并发系统中对流量的把控是非常重要的,当巨大的流量直接请求到我们的服务器上没多久就可能造成接口不可用,不处理的话甚至会造成整个应用