Kotlin中的Flow流

Kotlin Flow 是 Android 开发中推荐的异步数据流 解决方案。它基于 Kotlin 协程(Coroutines)构建,功能强大且灵活,旨在替代 RxJava 和部分 LiveData 的使用场景。

我们可以把它理解成一个管道:

上游(Upstream) :负责生产数据(如:从数据库读数据、网络请求)。

中游(Intermediaries) :负责处理数据(如:过滤 filter、转换 map)。

下游(Downstream) :负责接收/消费数据(如:更新 UI)。

核心概念: 冷流VS热流

特性 Cold Flow (普通 Flow) Hot Flow (StateFlow / SharedFlow)
激活时机 只有被收集(collect)时才开始运行。 无论有无收集者,它都在内存中活跃(类似于 LiveData)。
数据生产 是一对一的(Unicast)。每个收集者都会触发一遍新的数据生产流程。 是一对多的(Multicast)。多个收集者共享同一个数据源。
典型场景 耗时的数据库读取、文件下载、简单的异步转换。 UI 状态管理 (StateFlow)、一次性事件 (SharedFlow)。

具体例子:

A. Flow (普通冷流)

最基础的类型。用于执行耗时任务并按顺序发射多个值。

kotlin 复制代码
// 例子:倒计时
fun countdownFlow(): Flow<Int> = flow {
    for (i in 5 downTo 0) {
        emit(i) // 发射数据
        delay(1000) // 挂起函数,不阻塞线程
    }
}

B. StateFlow (热流 - 状态持有者)

它是 LiveData 的现代替代品。

  • 特点 :始终持有最新的一个状态值。新的收集者加入时,会立刻收到当前最新的值。
  • 场景:用于存储 UI 状态(如:Loading、Success、Error)。
  • 对比 LiveDataStateFlow 必须有初始值,且完全支持协程操作符。
kotlin 复制代码
// ViewModel 中
private val _uiState = MutableStateFlow("Initial State")
val uiState: StateFlow<String> = _uiState.asStateFlow()
​
// 更新状态
_uiState.value = "New State"

C. SharedFlow (热流 - 事件流)

  • 特点 :用于发送一次性事件 (One-off events)。默认不保留旧数据(除非配置 replay),新收集者不会收到过去发出的事件。
  • 场景:导航跳转、弹出 Toast、显示 Snackbar、服务器推送消息。
arduino 复制代码
// ViewModel 中
private val _events = MutableSharedFlow<String>()
val events: SharedFlow<String> = _events.asSharedFlow()
​
// 发送事件 (suspend function)
_events.emit("Show Toast")

在UI中安全收集

a. 在 Activity / Fragment (使用 Views)

使用 repeatOnLifecycle。它会在特定的生命周期状态(通常是 STARTED)开始收集,在低于该状态(如后台 STOPPED)时自动取消协程,停止接收数据。

javascript 复制代码
// 在 Activity 或 Fragment 中
lifecycleScope.launch {
    // 只有当生命周期至少是 STARTED 时才执行块内代码
    repeatOnLifecycle(Lifecycle.State.STARTED) {
        // 这两个流会并行收集
        launch {
            viewModel.uiState.collect { state ->
                // 更新 UI
            }
        }
        launch {
            viewModel.events.collect { event ->
                // 处理事件
            }
        }
    }
}

b. compose

使用 collectAsStateWithLifecycle()。它会自动将 Flow 转换为 Compose 的 State,并感知生命周期。

kotlin 复制代码
@Composable
fun MyScreen(viewModel: MyViewModel) {
    // 需要引入依赖: androidx.lifecycle:lifecycle-runtime-compose
    val state by viewModel.uiState.collectAsStateWithLifecycle()
    
    Text(text = state)
}

常用操作符

转换类map (数据映射), transform (自定义转换)

过滤类filter (过滤), debounce (防抖,搜索框必备), distinctUntilChanged (防重复,StateFlow 默认自带此特性)

组合类combine (合并多个流), zip, flatMapLatest (切换流,例如搜索词变化时取消旧请求发新请求)

异常处理catch (捕获上游异常)

线程切换flowOn(Dispatchers.IO) (指定上游代码在 IO 线程执行)

相关推荐
洞见不一样的自己1 小时前
Android studio 编译问题
android
j***63081 小时前
SpringbootActuator未授权访问漏洞
android·前端·后端
YJlio2 小时前
进程和诊断工具学习笔记(8.29):ListDLLs——一眼看清进程里加载了哪些 DLL,谁在偷偷注入
android·笔记·学习
你的乔克叔叔2 小时前
四大组件-Activity
android
aqi002 小时前
FFmpeg开发笔记(九十二)基于Kotlin的开源Android推流器StreamPack
android·ffmpeg·kotlin·音视频·直播·流媒体
Aileen_0v05 小时前
【Gemini3.0的国内use教程】
android·人工智能·算法·开源·mariadb
浩浩的代码花园6 小时前
自研端侧推理模型实测效果展示
android·深度学习·计算机视觉·端智能
踢球的打工仔12 小时前
PHP面向对象(7)
android·开发语言·php
安卓理事人12 小时前
安卓socket
android