android kotlin Flow
时间: 2025-02-01 19:48:45 浏览: 46
### 使用Kotlin Flow进行响应式编程
#### 创建和发射Flow
`Flow` 是一种冷流,意味着它不会自动执行直到被收集。创建 `Flow` 的方式有很多,最常见的是使用 `flow { }` 构建器。
```kotlin
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
fun simple(): Flow<Int> = flow {
for (i in 1..3) {
emit(i)
}
}
```
此代码定义了一个简单的整数序列生成器[^2]。
#### 收集Flow中的数据
要消费由 `Flow` 发射的数据项,则需调用 `collect()` 函数并提供一个挂起 lambda 表达式的参数,在每次接收到新值时都会被执行。
```kotlin
import kotlinx.coroutines.runBlocking
runBlocking {
simple().collect { value -> println(value) }
}
```
这段代码会打印出从简单流中发出的三个数值。
#### 处理异常情况
当遇到错误时,可以通过捕获异常来优雅地处理它们;也可以利用内置的操作符如 `catch` 或者 `retryWhen` 来增强健壮性。
```kotlin
val numbers = flowOf(1, 2, 3).map { it / 0 }.onEach { println(it) }
numbers.catch { e ->
if (e is ArithmeticException) emit(-1) else throw e
}.collect { println(it) }
```
这里展示了如果除零发生算术异常则替换为 `-1` 输出[^4]。
#### 组合多个Flows
有时可能希望将几个不同的 `Flow` 结合起来形成一个新的单一输出源。这可通过多种组合运算符完成,比如 `combine()`, `zip()`, 和 `flatMapConcat()/flatMapMerge()/transformLatest()` 等等。
```kotlin
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.*
val nums = flowOf(1, 2, 3).delayEach(100L)
val strs = flowOf("one", "two", "three").delayEach(200L)
nums.zip(strs) { a, b -> "$a -> $b" }
.collect { println(it) }
```
上述例子说明了怎样同步来自不同源头的信息流,并按顺序配对元素一起传递给下游消费者。
#### 集成到ViewModel与LiveData
为了使基于MVVM架构的应用能够监听UI层的变化,通常会在 ViewModel 中暴露 LiveData 类型属性供 Activity/Fragment 订阅更新状态变化。此时可以借助于 `StateFlow` 或者 `SharedFlow` 将内部私有的 `MutableStateFlow/MutableSharedFlow` 转换成只读形式对外发布出去。
```kotlin
class MyViewModel : ViewModel() {
private val _uiState = MutableStateFlow("")
val uiState: StateFlow<String>
get() = _uiState.asStateFlow()
fun updateUi(text: String){
viewModelScope.launch{
_uiState.emit(text)
}
}
}
```
在这个片段里,每当 `_uiState` 变化时就会触发所有观察者的回调方法去刷新界面显示的内容。
阅读全文
相关推荐




















