Flow/SharedFlow/StateFlow
LiveData特点
- LiveData具有感知生命周期,避免内存泄漏
- LiveData只能主线程更新数据,
postValue
本质调用setValue
- LiveData功能有限,不适合处理复杂数据
- 频繁请求数据容易数据丢失
Flow
- Flow是Kotlin协程与响应式编程模型结合的产物
- Flow功能强大,支持线程切换、背压
- Flow默认是冷流,只有调用
collect
订阅后,才会开始执行发射数据流的代码,有懒加载的特点
SharedFlow
- Flow是冷流,与订阅者只能是一对一的关系
- 而SharedFlow是热流,会立即发射消息,可以实现一对多的关系即共享 的Flow
SharedFlow构造函数
public fun <T> MutableSharedFlow(
replay: Int = 0,
extraBufferCapacity: Int = 0,
onBufferOverflow: BufferOverflow = BufferOverflow.SUSPEND
):
- replay:是否接受collect前的数据,默认为0,不会接收以前的数据
- extraBufferCapacity:减去replay后的缓冲空间
- onBufferOverflow:缓存策略,即缓冲区装满后Flow处理方式,默认为挂起
Activity
lifecycleScope.launch {
viewModel.sharedFlow.collect {
log("SharedFlow collect:$it")
}
}
ViewModel
private val _sharedFlow = MutableSharedFlow<Int>()
val sharedFlow = _sharedFlow.asSharedFlow()
var count = 0
fun count1() {
viewModelScope.launch {
_sharedFlow.emit(count++)
}
}
冷流转SharedFlow
- 普通Flow可以通过
sharedIn()
扩展方法,转位SharedFlow
public fun <T> Flow<T>.shareIn(
scope: CoroutineScope,
started: SharingStarted,
replay: Int = 0
):
- scope:协程作用域
- started:控制共享的开始和结束策略
- replay:状态流重播个数
lifecycleScope.launch {
kotlinx.coroutines.flow.flow<String> {
emit("a")
emit("b")
emit("c")
emit("d")
emit("e")
emit("f")
}
.shareIn(
lifecycleScope,
SharingStarted.WhileSubscribed()
).collect {
log("SharedFlow1 collect:$it")
}
}
StateFlow
- StateFlow是SharedFlow的变种,与LiveData特性较为接近
- StateFlow必须传入一个默认值,它的值是唯一的,可以有多个观察者也是共享Flow
- 永远只会把最新的值发给订阅者
Activity
lifecycleScope.launch {
viewModel.stateFlow.collect {
log("StateFlow collect:$it")
}
}
ViewModel
private val _stateFlow = MutableStateFlow<Int>(count)
val stateFlow = _stateFlow.asStateFlow()
var count = 0
fun count2() {
viewModelScope.launch {
_stateFlow.value = count++
}
}