Skip to content

12. Kotlin Flow 操作符详解

目录

  1. Flow 基础概念(冷数据流)
  2. Cold vs Hot Flow
  3. StateFlow 详解
  4. SharedFlow 详解
  5. Flow 转换操作符
  6. Flow 过滤操作符
  7. Flow 组合操作符
  8. Flow 异常操作符
  9. Flow 终端操作符
  10. Flow 与 LiveData 对比
  11. Flow 与 RxJava 对比
  12. Flow 性能优化
  13. 最佳实践
  14. 面试考点

1. Flow 基础概念(冷数据流)

1.1 什么是 Flow

Flow 是 Kotlin 协程提供的响应式数据流,从 Kotlin 1.3.40 开始引入。它是一种冷数据流(Cold Data Stream),意味着每次收集时都会重新执行产生数据的操作。

kotlin
import kotlinx.coroutines.flow.*

// 创建 Flow
val flow: Flow<Int> = flow {
    emit(1)
    emit(2)
    emit(3)
}

// 收集 Flow
flow.collect { value ->
    println("Received: $value")
}

1.2 Flow 的冷数据流特性

kotlin
// Flow 是冷的:每次 collect 都会重新执行
val coldFlow = flow {
    println("Producing data...")
    emit(1)
    emit(2)
    emit(3)
}

// 第一次收集
println("First collection:")
coldFlow.collect { println("  -> $it") }

// 第二次收集
println("\nSecond collection:")
coldFlow.collect { println("  -> $it") }

// 输出:
// First collection:
// Producing data...
//   -> 1
//   -> 2
//   -> 3
// 
// Second collection:
// Producing data...
//   -> 1
//   -> 2
//   -> 3

1.3 Flow 与 Iterable 对比

kotlin
// Iterable:同步、阻塞
val list = listOf(1, 2, 3, 4, 5)
list.forEach { println(it) }  // 同步执行

// Flow:异步、非阻塞
val flow = flowOf(1, 2, 3, 4, 5)
flow.collect { println(it) }  // 异步收集

// Flow 支持 suspend 函数
suspend fun fetchData(): Data {
    delay(1000)
    return Data("Result")
}

val flowWithSuspend = flow {
    val data = fetchData()  // 可以在 Flow 中使用 suspend 函数
    emit(data)
}

1.4 Flow 构建器

kotlin
// flow {} 构建器
val customFlow = flow<Int> {
    for (i in 1..5) {
        delay(100)
        emit(i)
    }
}

// flowOf() - 从集合创建
val simpleFlow = flowOf(1, 2, 3, 4, 5)

// asFlow() - 从 Iterable 转换
val listAsFlow = listOf(1, 2, 3).asFlow()

// channelAsFlow() - 从 Channel 转换
val channel = Channel<Int>()
val channelFlow = channel.asFlow()

1.5 Flow 的基本结构

kotlin
// Flow 的基本结构
interface Flow<out T> {
    suspend fun collect(collector: FlowCollector<T>)
}

// 使用示例
val flow = flow {
    // 生产者代码
    emit(1)
    emit(2)
}.map { it * 2 }  // 转换操作

flow.collect { value ->
    // 消费者代码
    println(value)
}

2. Cold vs Hot Flow

2.1 Cold Flow(冷数据流)

kotlin
// Cold Flow:每次收集都重新执行
val coldFlow = flow {
    println("Starting production...")
    emit(1)
    emit(2)
    emit(3)
}

// 多个收集器
coldFlow.collect { println("Collector 1: $it") }
coldFlow.collect { println("Collector 2: $it") }

// 每个收集器都会重新执行生产者代码

2.2 Hot Flow(热数据流)

kotlin
// Hot Flow:独立于收集器运行
val hotFlow = MutableSharedFlow<Int>()

// 发射数据(即使没有收集器)
hotFlow.emit(1)
hotFlow.emit(2)

// 多个收集器共享同一个数据流
hotFlow.collect { println("Collector 1: $it") }
hotFlow.collect { println("Collector 2: $it") }

2.3 Cold vs Hot 对比

特性Cold FlowHot Flow
执行时机collect 时执行独立执行
多个收集器各自执行共享执行
状态保持无状态有状态
内存占用较高
典型类型FlowStateFlow, SharedFlow

2.4 冷流转热流

kotlin
// 使用 shareIn 将冷流转为热流
val coldFlow = flow {
    println("Producing...")
    emit(1)
    emit(2)
}

// 转为热流
val hotFlow = coldFlow.shareIn(
    scope = viewModelScope,
    started = SharingStarted.WhileSubscribed(5000)
)

// 多个收集器共享
hotFlow.collect { println("1: $it") }
hotFlow.collect { println("2: $it") }

2.5 使用场景

kotlin
// Cold Flow 场景
// - 网络请求
// - 数据库查询
// - 文件读取

val apiFlow = flow {
    val data = api.fetchData()
    emit(data)
}

// Hot Flow 场景
// - UI 状态
// - 实时数据
// - 传感器数据

val uiStateFlow = MutableStateFlow<UiState>(UiState.Initial)

3. StateFlow 详解

3.1 StateFlow 基础

kotlin
// StateFlow 是热数据流,保持当前状态
val stateFlow = MutableStateFlow<Int>(0)

// 发射值
stateFlow.value = 1
stateFlow.value = 2

// 收集
stateFlow.collect { value ->
    println("Value: $value")
}

3.2 StateFlow 特性

kotlin
// 1. 保存当前状态
val stateFlow = MutableStateFlow<String>("Initial")

// 2. 新收集器立即收到当前值
stateFlow.value = "Updated"
stateFlow.collect { println("Received: $it") }  // 立即收到 "Updated"

// 3. 不可为 null(使用 StateFlow<T>)
// stateFlow.value = null  // 编译错误

3.3 StateFlow 与 LiveData

kotlin
// LiveData
val liveData = MutableLiveData<String>()
liveData.value = "Hello"

// StateFlow
val stateFlow = MutableStateFlow<String>("Hello")
stateFlow.value = "World"

// StateFlow 优势
// 1. 更好的空安全
// 2. 支持协程
// 3. 更强大的操作符

3.4 StateFlow 在 ViewModel 中

kotlin
class MyViewModel : ViewModel() {
    // 私有可变 StateFlow
    private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
    
    // 公开只读 StateFlow
    val uiState: StateFlow<UiState> = _uiState.asStateFlow()
    
    fun loadData() {
        viewModelScope.launch {
            _uiState.value = UiState.Loading
            try {
                val data = repository.fetchData()
                _uiState.value = UiState.Success(data)
            } catch (e: Exception) {
                _uiState.value = UiState.Error(e)
            }
        }
    }
}

// UI 层观察
class MyActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        lifecycleScope.launch {
            viewModel.uiState.collect { state ->
                when (state) {
                    is UiState.Loading -> showLoading()
                    is UiState.Success -> showData(state.data)
                    is UiState.Error -> showError(state.error)
                }
            }
        }
    }
}

3.5 StateFlow 转换

kotlin
// map 转换
val mappedFlow = stateFlow.map { it * 2 }

// filter 过滤
val filteredFlow = stateFlow.filter { it > 0 }

// flatMap 平铺
val flatMappedFlow = stateFlow.flatMapLatest { id ->
    getUserFlow(id)
}

3.6 StateFlow 初始值

kotlin
// 必须提供初始值
val stateFlow = MutableStateFlow<Int>(0)  // 初始值为 0

// 使用 sealed class 初始值
sealed class UiState {
    object Loading : UiState()
    data class Success(val data: Data) : UiState()
    data class Error(val error: String) : UiState()
}

val uiStateFlow = MutableStateFlow<UiState>(UiState.Loading)

4. SharedFlow 详解

4.1 SharedFlow 基础

kotlin
// SharedFlow 是热数据流,不保存历史值
val sharedFlow = MutableSharedFlow<Int>()

// 发射值
sharedFlow.emit(1)
sharedFlow.emit(2)

// 收集(只会收到 emit 后的值)
sharedFlow.collect { println("Received: $it") }

4.2 SharedFlow 配置

kotlin
// 配置 SharedFlow
val sharedFlow = MutableSharedFlow<Int>(
    replay = 0,           // 重放值数量(默认 0)
    bufferSize = 0,       // 缓冲区大小(0=CHANNEL_BUFFERED)
    extraBufferHandling = null,  // 额外缓冲区处理
    onBufferOverflow = SharedFlow.BufferOverflow.DROP_LATEST  // 溢出处理
)

// 发射
sharedFlow.emit(1)
sharedFlow.emit(2)

4.3 SharedFlow 溢出策略

kotlin
// BufferOverflow.DROP_LATEST - 丢弃最新值(默认)
val dropLatest = MutableSharedFlow<Int>(
    onBufferOverflow = SharedFlow.BufferOverflow.DROP_LATEST
)

// BufferOverflow.DROP_OLDEST - 丢弃最旧值
val dropOldest = MutableSharedFlow<Int>(
    onBufferOverflow = SharedFlow.BufferOverflow.DROP_OLDEST
)

// BufferOverflow.SUSPEND - 挂起发射
val suspendEmit = MutableSharedFlow<Int>(
    onBufferOverflow = SharedFlow.BufferOverflow.SUSPEND
)

4.4 SharedFlow 重放

kotlin
// 重放最后 N 个值
val replaySharedFlow = MutableSharedFlow<Int>(
    replay = 3
)

replaySharedFlow.emit(1)
replaySharedFlow.emit(2)
replaySharedFlow.emit(3)

// 新收集器会收到 1, 2, 3
replaySharedFlow.collect { println("Received: $it") }

4.5 SharedFlow 使用场景

kotlin
// 场景 1:事件流(不重放)
class MyViewModel : ViewModel() {
    val _event = MutableSharedFlow<UiEvent>()
    val event: SharedFlow<UiEvent> = _event.asSharedFlow()
    
    fun triggerEvent() {
        viewModelScope.launch {
            _event.emit(UiEvent.ShowToast("Done"))
        }
    }
}

// 场景 2:需要重放的流
val configFlow = MutableSharedFlow<Config>(replay = 1)

4.6 SharedFlow 与 StateFlow 对比

kotlin
// StateFlow:保存状态,新收集器收到当前值
val stateFlow = MutableStateFlow<String>("Initial")
stateFlow.value = "Updated"
stateFlow.collect { println(it) }  // 输出 "Updated"

// SharedFlow:不保存状态,新收集器只收到新值
val sharedFlow = MutableSharedFlow<String>()
sharedFlow.emit("Initial")
sharedFlow.emit("Updated")
sharedFlow.collect { println(it) }  // 不输出,除非 emit 后收集

5. Flow 转换操作符

5.1 map

kotlin
// map - 转换元素
val flow = flowOf(1, 2, 3, 4, 5)

val mapped = flow.map { it * 2 }
mapped.collect { println(it) }  // 2, 4, 6, 8, 10

// map 带索引
val withIndex = flow.mapIndexed { index, value ->
    "${index}: $value"
}
withIndex.collect { println(it) }  // "0: 1", "1: 2", ...

5.2 flatMap

kotlin
// flatMap - 平铺嵌套 Flow
val outerFlow = flowOf(1, 2, 3)

val flatMapped = outerFlow.flatMap { number ->
    flowOf(number, number * 2, number * 3)
}

flatMapped.collect { println(it) }  
// 1, 2, 3, 2, 4, 6, 3, 6, 9

5.3 flatMapLatest

kotlin
// flatMapLatest - 取消之前的 Flow,只保留最新的
val searchQueryFlow = MutableSharedFlow<String>()

val resultFlow = searchQueryFlow.flatMapLatest { query ->
    searchApi(query)  // 每次新查询,取消之前的请求
}

resultFlow.collect { println(it) }

5.4 flatMapConcat

kotlin
// flatMapConcat - 按顺序执行,不取消之前的
val flow = flowOf(1, 2, 3)

val concatenated = flow.flatMapConcat { number ->
    flow {
        delay(100)
        emit(number * 2)
        delay(100)
        emit(number * 3)
    }
}

concatenated.collect { println(it) }
// 按顺序:2, 3, 4, 6, 6, 9

5.5 flatMapMerge

kotlin
// flatMapMerge - 并发执行,合并结果
val flow = flowOf(1, 2, 3)

val merged = flow.flatMapMerge { number ->
    flow {
        delay(number * 100)
        emit(number * 2)
    }
}

merged.collect { println(it) }
// 并发执行,顺序不定

5.6 combine

kotlin
// combine - 合并多个 Flow
val flow1 = flowOf(1, 2, 3)
val flow2 = flowOf("a", "b", "c")

val combined = flow1.combine(flow2) { num, str ->
    "$num-$str"
}

combined.collect { println(it) }
// 每次有新值时组合:1-a, 2-b, 3-c

5.7 zip

kotlin
// zip - 组合多个 Flow 的元素
val flow1 = flowOf(1, 2, 3)
val flow2 = flowOf("a", "b", "c", "d")

val zipped = flow1.zip(flow2) { num, str ->
    "$num-$str"
}

zipped.collect { println(it) }
// 1-a, 2-b, 3-c(以最短的 Flow 为准)

5.8 transform

kotlin
// transform - 转换并可以发射多个值
val flow = flowOf(1, 2, 3)

val transformed = flow.transform { value ->
    emit(value)
    emit(value * 2)
    emit(value * 3)
}

transformed.collect { println(it) }
// 1, 2, 3, 2, 4, 6, 3, 6, 9

6. Flow 过滤操作符

6.1 filter

kotlin
// filter - 过滤元素
val flow = flowOf(1, 2, 3, 4, 5)

val filtered = flow.filter { it > 2 }
filtered.collect { println(it) }  // 3, 4, 5

// filterIndexed
val filteredIndexed = flow.filterIndexed { index, value ->
    index % 2 == 0
}
filteredIndexed.collect { println(it) }  // 1, 3, 5

6.2 filterNot

kotlin
// filterNot - 反向过滤
val flow = flowOf(1, 2, 3, 4, 5)

val filteredNot = flow.filterNot { it % 2 == 0 }
filteredNot.collect { println(it) }  // 1, 3, 5

6.3 filterDistinct

kotlin
// filterDistinct - 过滤重复值
val flow = flowOf(1, 1, 2, 2, 3, 3)

val distinct = flow.distinctUntilChanged()
distinct.collect { println(it) }  // 1, 2, 3

6.4 take

kotlin
// take - 取前 N 个元素
val flow = flowOf(1, 2, 3, 4, 5)

val taken = flow.take(3)
taken.collect { println(it) }  // 1, 2, 3

6.5 takeWhile

kotlin
// takeWhile - 取直到条件不满足
val flow = flowOf(1, 2, 3, 4, 5)

val takenWhile = flow.takeWhile { it < 4 }
takenWhile.collect { println(it) }  // 1, 2, 3

6.6 drop

kotlin
// drop - 丢弃前 N 个元素
val flow = flowOf(1, 2, 3, 4, 5)

val dropped = flow.drop(2)
dropped.collect { println(it) }  // 3, 4, 5

6.7 first

kotlin
// first - 获取第一个元素
val flow = flowOf(1, 2, 3)

val first = flow.first()
println(first)  // 1

// first 带条件
val firstGreater = flow.first { it > 1 }
println(firstGreater)  // 2

6.8 single

kotlin
// single - 确保只有一个元素
val singleFlow = flowOf(1)

val single = singleFlow.single()
println(single)  // 1

// 多个元素会抛异常
try {
    flowOf(1, 2).single()  // IllegalArgumentException
} catch (e: Exception) {
    println("Error: ${e.message}")
}

6.9 skip

kotlin
// skip - 跳过前 N 个元素(与 drop 相同)
val flow = flowOf(1, 2, 3, 4, 5)

val skipped = flow.skip(2)
skipped.collect { println(it) }  // 3, 4, 5

7. Flow 组合操作符

7.1 merge

kotlin
// merge - 合并多个 Flow
val flow1 = flowOf(1, 2, 3)
val flow2 = flowOf("a", "b", "c")

val merged = flow1.merge(flow2)
merged.collect { println(it) }
// 交错输出:1, a, 2, b, 3, c

7.2 mergeMany

kotlin
// mergeMany - 合并嵌套 Flow
val outerFlow = flowOf(
    flowOf(1, 2),
    flowOf(3, 4),
    flowOf(5, 6)
)

val mergedMany = outerFlow.mergeMany()
mergedMany.collect { println(it) }
// 1, 2, 3, 4, 5, 6

7.3 concat

kotlin
// concat - 连接多个 Flow
val flow1 = flowOf(1, 2, 3)
val flow2 = flowOf(4, 5, 6)

val concatenated = flow1.concat(flow2)
concatenated.collect { println(it) }
// 1, 2, 3, 4, 5, 6

7.4 concatMany

kotlin
// concatMany - 按顺序连接嵌套 Flow
val outerFlow = flowOf(
    flowOf(1, 2),
    flowOf(3, 4),
    flowOf(5, 6)
)

val concatMany = outerFlow.concatMany()
concatMany.collect { println(it) }
// 1, 2, 3, 4, 5, 6(按顺序)

7.5 onEach

kotlin
// onEach - 在发射时执行操作
val flow = flowOf(1, 2, 3)

val withSideEffect = flow.onEach { value ->
    println("Emitting: $value")
}

withSideEffect.collect { println("Received: $it") }

7.6 onStart

kotlin
// onStart - 在开始收集时执行
val flow = flowOf(1, 2, 3)

val withStart = flow.onStart {
    println("Collection started")
}

withStart.collect { println("Received: $it") }

7.7 onComplete

kotlin
// onComplete - 在完成收集时执行
val flow = flowOf(1, 2, 3)

val withComplete = flow.onCompletion { throwable ->
    if (throwable == null) {
        println("Completed normally")
    } else {
        println("Completed with error: $throwable")
    }
}

withComplete.collect { println("Received: $it") }

8. Flow 异常操作符

8.1 catch

kotlin
// catch - 捕获异常
val flow = flow {
    emit(1)
    throw Exception("Error")
    emit(2)  // 不会执行
}

val caught = flow.catch { e ->
    println("Caught: ${e.message}")
    emit(0)  // 发射默认值
}

caught.collect { println("Received: $it") }

8.2 retry

kotlin
// retry - 重试失败的操作
val flow = flow {
    attemptCount++
    if (attemptCount < 3) {
        throw Exception("Attempt $attemptCount")
    }
    emit("Success")
}

var attemptCount = 0
val retried = flow.retry(2) { e ->
    println("Retry: ${e.message}")
    true  // 继续重试
}

retried.collect { println("Result: $it") }

8.3 retryWhen

kotlin
// retryWhen - 有条件重试
val flow = flow {
    attemptCount++
    if (attemptCount < 3) {
        throw Exception("Attempt $attemptCount")
    }
    emit("Success")
}

var attemptCount = 0
val retryWhenFlow = flow.retryWhen { cause, attempt ->
    if (attempt < 2 && cause is IOException) {
        println("Retry attempt $attempt")
        delay(1000 * (attempt + 1))
        true
    } else {
        false
    }
}

8.4 handleException

kotlin
// handleException - 处理异常
val flow = flow {
    emit(1)
    throw Exception("Error")
}

val handled = flow.handleException { e ->
    println("Handled: ${e.message}")
}

handled.collect { println("Received: $it") }

9. Flow 终端操作符

9.1 collect

kotlin
// collect - 终端操作符,开始收集
val flow = flowOf(1, 2, 3)

flow.collect { value ->
    println("Received: $value")
}

// collect 是 suspend 函数
suspend fun processFlow() {
    flow.collect { /* ... */ }
}

9.2 collectLatest

kotlin
// collectLatest - 取消之前的收集,只处理最新的
val flow = MutableSharedFlow<Int>()

flow.collectLatest { value ->
    println("Processing: $value")
    delay(1000)
}

9.3 collectWhile

kotlin
// collectWhile - 条件收集
val flow = flowOf(1, 2, 3, 4, 5)

flow.collectWhile { value ->
    value < 4
} {
    println("Received: $it")
}
// 1, 2, 3

9.4 launchIn

kotlin
// launchIn - 在作用域中自动启动收集
val flow = flowOf(1, 2, 3)

flow.launchIn(viewModelScope) { value ->
    println("Received: $value")
}

9.5 first

kotlin
// first - 获取第一个元素
val flow = flowOf(1, 2, 3)

val first = flow.first()
println(first)  // 1

// first 带条件
val firstEven = flow.first { it % 2 == 0 }
println(firstEven)  // 2

9.6 single

kotlin
// single - 确保只有一个元素
val singleFlow = flowOf(1)
val single = singleFlow.single()
println(single)  // 1

9.7 reduce

kotlin
// reduce - 归约
val flow = flowOf(1, 2, 3, 4, 5)

val sum = flow.reduce { acc, value ->
    acc + value
}
println(sum)  // 15

9.8 fold

kotlin
// fold - 带初始值的归约
val flow = flowOf(1, 2, 3, 4, 5)

val sum = flow.fold(0) { acc, value ->
    acc + value
}
println(sum)  // 15

10. Flow 与 LiveData 对比

10.1 LiveData 基础

kotlin
// LiveData
val liveData = MutableLiveData<String>()
liveData.value = "Hello"

// 观察
liveData.observe(lifecycleOwner) { value ->
    println(value)
}

10.2 Flow 与 LiveData 对比

特性LiveDataFlow
生命周期感知需要 lifecycleScope
线程切换需要 withContext
操作符有限丰富
协程支持
空安全一般优秀

10.3 LiveData 转 Flow

kotlin
// LiveData 转 Flow
val liveData = MutableLiveData<String>()

val flow = liveData.asFlow()
flow.collect { println(it) }

10.4 Flow 转 LiveData

kotlin
// Flow 转 LiveData
val flow = flowOf("Hello", "World")

val liveData = MediatorLiveData<String>().apply {
    sourceFlow = flow.asLiveData()
}

10.5 使用建议

kotlin
// 新推荐使用 Flow
// 1. 更好的协程支持
// 2. 更丰富的操作符
// 3. 更好的空安全

// LiveData 仍然有用
// 1. 与现有代码兼容
// 2. 生命周期感知

11. Flow 与 RxJava 对比

11.1 RxJava 基础

kotlin
// RxJava
Observable.create<Int> { emitter ->
    emitter.onNext(1)
    emitter.onNext(2)
    emitter.onNext(3)
}.subscribe {
    println(it)
}

11.2 Flow 与 RxJava 对比

特性RxJavaFlow
学习曲线陡峭平缓
性能
操作符非常丰富足够
协程集成需要适配原生支持
调试困难容易

11.3 Flow 替代 RxJava

kotlin
// RxJava: map + filter
observable.map { it * 2 }
          .filter { it > 2 }
          .subscribe { println(it) }

// Flow: 相同操作
flow.map { it * 2 }
    .filter { it > 2 }
    .collect { println(it) }

11.4 RxJava 转 Flow

kotlin
// Observable 转 Flow
val observable = Observable.fromIterable(listOf(1, 2, 3))

val flow = observable.asFlow()
flow.collect { println(it) }

12. Flow 性能优化

12.1 减少不必要的操作

kotlin
// 优化:减少操作符链
val optimized = flow
    .filter { it > 0 }
    .map { it * 2 }
    .collect { println(it) }

// 避免:嵌套操作符
val unoptimized = flow
    .map { flowOf(it, it * 2) }
    .flatMap { it }
    .collect { println(it) }

12.2 使用 buffer

kotlin
// buffer - 缓冲数据
val flow = flowOf(1, 2, 3, 4, 5)

val buffered = flow.buffer(10)
buffered.collect { println(it) }

12.3 使用 flowOn

kotlin
// flowOn - 指定生产者线程
val flow = flowOf(1, 2, 3)

val withFlowOn = flow
    .flowOn(Dispatchers.IO)
    .map { it * 2 }
    .flowOn(Dispatchers.Default)
    .collect { println(it) }

12.4 缓存

kotlin
// 缓存 Flow 结果
val cachedFlow = flow.cache(3)

13. 最佳实践

13.1 命名规范

kotlin
// Flow 命名
val userFlow: Flow<User>
val uiStateFlow: StateFlow<UiState>
val eventFlow: SharedFlow<UiEvent>

13.2 错误处理

kotlin
// 错误处理
val flow = flow {
    try {
        emit(fetchData())
    } catch (e: Exception) {
        emit(DefaultData)
    }
}

13.3 测试

kotlin
// 测试 Flow
@Test
fun testFlow() = runTest {
    val flow = flowOf(1, 2, 3)
    val result = flow.toList()
    assertEquals(listOf(1, 2, 3), result)
}

14. 面试考点

14.1 基础考点

Q1: Flow 是什么?它与 LiveData 的区别?

A:

  • Flow 是冷数据流,需要收集才执行
  • LiveData 是生命周期感知数据持有者
  • Flow 支持协程,LiveData 不支持

Q2: StateFlow 和 SharedFlow 的区别?

A:

  • StateFlow 保存当前状态,新收集器收到当前值
  • SharedFlow 不保存状态,新收集器只收到新值

Q3: Cold Flow 和 Hot Flow 的区别?

A:

  • Cold Flow:每次收集都重新执行
  • Hot Flow:独立于收集器运行

14.2 进阶考点

Q4: flatMapLatest 的用途?

A:

  • 用于搜索场景,取消之前的请求
  • 只保留最新的 Flow

Q5: 如何实现 Flow 的重试?

A:

kotlin
flow.retry(3) { e -> true }

14.3 高级考点

Q6: Flow 的背压处理?

A:

  • 使用 SharedFlow 的 onBufferOverflow
  • 使用 buffer 操作符

Q7: 如何优化 Flow 性能?

A:

  • 减少操作符链
  • 使用 flowOn 指定线程
  • 使用缓存

总结

Kotlin Flow 是响应式编程的强大工具,提供了丰富的操作符和协程支持。掌握 Flow 的基础概念、冷热流区别、StateFlow/SharedFlow、操作符使用和性能优化,对于构建现代化的 Android 应用至关重要。

核心要点:

  1. 冷数据流 - Flow 是冷的
  2. StateFlow vs SharedFlow - 状态 vs 事件
  3. 操作符 - 丰富的转换和过滤
  4. 错误处理 - catch 和 retry
  5. 性能优化 - 合理设计