Flow知识点汇总
livedata对比特性
- 感知生命周期
- 只能在主线程操作
- postValue 丢失数据
- 单一数据
- 支持java和kotlin
- 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 事件处理、事件总线、消息队列,重播特定数量
冷流转换为热流
- 冷流转换为热流,保证取出的是最新的值
stateIn 和 shareIn
callbackFlow
private fun getCallBackFlow():Flow<Int> = callbackFlow{
trySend(1)
delay(200)
error("是的")
}
flow感知生命周期
- lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED)
- 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)
println("$value collected") }
}
Collecting
Collecting 2
2 collected
flow {
emit(1)
delay(50)
emit(2)
}.buffer(2, BufferOverflow.DROP_OLDEST).collect { value ->
println("Collecting $value")
delay(100)
println("$value collected")
}