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 线程执行)

相关推荐
问心无愧05137 小时前
ctf show web入门111
android·前端·笔记
ha_lydms13 小时前
AnalyticDB分区、分布键性能优化
android·大数据·分布式·性能优化·分布式计算·分区·analyticdb
星辰14 小时前
Ijkplayer重新编译支持h264裸流
android
测试开发-学习笔记14 小时前
Android studio安装
android·ide·android studio
宋拾壹14 小时前
同时添加多个类目
android·开发语言·javascript
●VON15 小时前
AtomGit Flutter鸿蒙客户端:数据模型
android·服务器·安全·flutter·harmonyos·鸿蒙
火柴就是我15 小时前
记录一个文本随手指缩放的功能
android
Zender Han16 小时前
Android APK 签名 v1、v2、v3、v4 有什么区别?
android
神仙别闹16 小时前
基于 PHP + MySQL学生信息管理系统
android·mysql·php
墨狂之逸才17 小时前
Android 保活机制详解 —— 从概念到实践
android