Flow/SharedFlow/StateFlow

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++
    }
}

代码下载

猜你喜欢

转载自blog.csdn.net/qq_14876133/article/details/119984626