Android-Flow 使用和源码解析

本文深入探讨了Android中Kotlin的Flow数据流的使用,包括创建、修改和收集数据的方法,以及冷流和热流的概念。重点介绍了StateFlow、SharedFlow的区别,以及如何在Android环境中有效利用Flow,如repeatOnLifecycle和flowWithLifecycle方法。同时,文章通过源码分析帮助读者更好地理解Flow的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

数据流以协程为基础构建,可提供多个值。从概念上来讲,数据流是可通过异步方式进行计算处理的一组数据序列。所发出值的类型必须相同。例如,Flow 是发出整数值的数据流。

在协程中,与仅返回单个值的挂起函数相反,数据流可按顺序发出多个值。

数据流包含三个实体:

  • 提供方会生成添加到数据流中的数据。得益于协程,数据流还可以异步生成数据。
  • (可选)中介可以修改发送到数据流的值,或修正数据流本身。
  • 使用方则使用数据流中的值。

在这里插入图片描述

1.使用

1.1 创建数据流

创建数据流有两种常用方式: 第一就是试用数据流构建函数, 第二就是利用扩展方法将原有类型转换成Flow

使用数据构建函数

这里比较常用的函数是 flow()flowOf()

val f = flow {
   
    emit(1)
}
val f2 = flowOf("abc")
val f3 = flowOf("A", "B", "C")

其实 flowof() 是简化版的 flow() 函数,内部帮我们调用了 emit()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JEWWqcWq-1670402003040)(/Users/apple/Downloads/job_files/flow/Xnip2022-11-20_00-25-28.jpg )]

注意:

使用 flow 构建器时,提供方不能提供来自不同 CoroutineContextemit 值。因此,请勿通过创建新协程或使用 withContext 代码块,在不同 CoroutineContext 中调用 emit 可以使用 flowOn 或者 callbackFlow

使用扩展方法

扩展方法是 kotlin 标准库中提供的 asFlow() . 目前基本上覆盖了基本数据类型、lambda、及挂起函数等

下面看一下具体如何使用:

普通lambda 表达式
fun testAsFlow1(blacking: () -> String) {
   
    val flow = blacking.asFlow()
}
挂起函数
suspend fun testAsFlow2(blacking: suspend () -> String) {
   
    val flow = blacking.asFlow()
}

或者以下方式:

suspend fun remoteCall(): String = withContext(Dispatchers.IO) {
   
    return@withContext "ABC"
}
fun remoteCallFlow(): Flow<String> = ::remoteCall.asFlow()
基本数据类型

kotlin 标准库中提供了基本数据类型相关扩展方法,其中 Map类型不能直接使用asFlow() 需要转换成其支持的类型,再使用 asFlow().

fun testAsFlow3() {
   

    // Range 类型
    val flow1 = IntRange(1, 100).asFlow()
    val flow2 = LongRange(1L, 1000L).asFlow()
    
    // Array 类型
    val flow3 = intArrayOf(1, 2, 3).asFlow()
    val flow4 = longArrayOf(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值