iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android开发flow常见API的使用示例详解
  • 119
分享到

Android开发flow常见API的使用示例详解

2024-04-02 19:04:59 119人浏览 安东尼
摘要

目录collect通知flow执行launchIn()指定协程作用域通知flow执行catch{}捕捉异常merge()合流map{}变换发送的数据类型总结collect通知flow

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")
        }
    }
}

总结

本篇文章介绍了flow常见的api,接下来还会有一些列文章用来介绍flow的其他api,更多关于Android开发flow常见API的资料请关注编程网其它相关文章!

--结束END--

本文标题: Android开发flow常见API的使用示例详解

本文链接: https://www.lsjlt.com/news/165774.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作