Flow知识点汇总

201 阅读2分钟

Flow知识点汇总

livedata对比特性

  1. 感知生命周期
  2. 只能在主线程操作
  3. postValue 丢失数据
  4. 单一数据
  5. 支持java和kotlin
  6. postValue 丢失数据
丢失代码分析
protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}

private final Runnable mPostValueRunnable = new Runnable() {
        @SuppressWarnings("unchecked")
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            setValue((T) newValue);
        }
};

Flow特点

  • 异步编程,协程支持
  • 更多的操作符
  • 连续数据流
  • 线程切换
  • 异常处理
  • 只能在kotlin 协程环境使用
  • 默认情况下不感知生命周期

冷流(flowOf、flow、asFlow)

  • 数据只有在有消费者(collect)时才开始生产。这意味着每个新的消费者会触发一个新的数据流。
  • 适合单播场景,每个消费者都会从头开始接收数据

热流(如StateFlow、SharedFlow)

  • 创建过后就会开始产生数据,无论是否有消费者,生产消费独立
  • 热流的collect会被阻塞

StateFlow

  • 提供StateFlow,MutableStateFlow
  • 它的值是唯一的
  • 它允许被多个观察者共用 (因此是共享的数据流)
  • 它永远只会把最新的值重现给订阅者,这与活跃观察者的数量是无关的
  • 支持 DataBinding
  • 自动去重

SharedFlow

  • 可以配置一定量的粘滞数据,和背压策略
  • 一个是状态(StateFlow),一个是事件(SharedFlow)
  • StateFlow 只保持最新的状态
  • SharedFlow 事件处理、事件总线、消息队列,重播特定数量

冷流转换为热流

  • 冷流转换为热流,保证取出的是最新的值 stateInshareIn

callbackFlow

 private fun getCallBackFlow():Flow<Int> = callbackFlow{
        trySend(1)
        delay(200)
        error("是的")
    }

flow感知生命周期

  1. lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED)
    • 当只需要在首次进入该生命周期时触发,需要自己管理
  2. Flow.flowWithLifecycle(lifecycle, Lifecycle.State.STARTED)

Flow操作符号

  • drop(n) 丢失前N个
  • dropWhile 丢弃直到
  • take(n)取前n个
  • takeWhile 取直到
  • debounce(time) 发送时间小于time,取消前面的数据,用于发送过快,只取最后的稳定数据
  • same(time) 上游发送的太快,只在指定time取样一次
  • 背压1 collectLast 上一条数据未处理完,取消上一条数据的处理过程(协程方面取消)
    flow {
            emit(1)
            delay(50)
            emit(2)
        }.collectLatest { value ->
            println("Collecting $value")
            delay(100) // Emulate work
            println("$value collected") }
        }
Collecting 
Collecting 2
2 collected	
  • 背压2 buffer 缓存上游数据
     flow {
                emit(1)
                delay(50)
                emit(2)
            }.buffer(2, BufferOverflow.DROP_OLDEST).collect { value ->
                println("Collecting $value")
                delay(100) // Emulate work
                println("$value collected")
            }
  • 被压3 conflate 每次只取最新的值