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

相关推荐
_李小白6 小时前
【Android FrameWork】延伸阅读:SurfaceFlinger线程
android
csdn12259873367 小时前
JetPack Compose 入门先搞清楚
android·compose·jetpack
liang_jy7 小时前
Android LaunchMode
android·面试
阿里云云原生8 小时前
Android App 崩溃排查实战:如何利用 RUM 完整数据与符号化技术定位问题?
android·阿里云·云原生·rum
过期动态9 小时前
JDBC高级篇:优化、封装与事务全流程指南
android·java·开发语言·数据库·python·mysql
没有了遇见11 小时前
Android 音乐播放器之MotionLayout实现View流畅变换
android
TheNextByte112 小时前
在 PC 和Android之间同步音乐的 4 种方法
android
君莫啸ོ12 小时前
Android基础-Activity属性 android:configChanges
android
TimeFine12 小时前
Android AI解放生产力(七):更丰富的AI运用前瞻
android
保持低旋律节奏12 小时前
linux——进程状态
android·linux·php