先总结,再分析:
- LiveData 的值被存储在内部的字段中,直到有更新的值覆盖,所以值是持久的。
- 两种场景下 LiveData 会将存储的值分发给观察者。一是值被更新,此时会遍历所有观察者并分发之。二是新增观察者或观察者生命周期发生变化(至少为 STARTED),此时只会给单个观察者分发值。
- LiveData 的观察者会维护一个“值的版本号”,用于判断上次分发的值是否是最新值。该值的初始值是-1,每次更新 LiveData 值都会让版本号自增。
- LiveData 并不会无条件地将值分发给观察者,在分发之前会经历三道坎:1. 数据观察者是否活跃。2. 数据观察者绑定的生命周期组件是否活跃。3. 数据观察者的版本号是否是最新的。
- “新观察者”被“老值”通知的现象叫“粘性”。因为新观察者的版本号总是小于最新版号,且添加观察者时会触发一次老值的分发。
如果把 sticky 翻译成“持久的”,会更好理解一些。数据是持久的,意味着它不是转瞬即逝的,不会因为被消费了就不见了,它会一直在那。而且当新的观察者被注册时,持久的数据会将最新的值分发给它。
“持久的数据”是怎么做到的?
显然是被存起来了。以更新 LiveData 数据的方法为切入点找找线索:
public abstract class LiveData<T> {
// 存储数据的字段
private volatile Object mData;
// 值版本号
private int mVersion;
// 更新值
protected void setValue(T value) {
assertMainThread("setValue");
// 版本号自增
mVersion++;
// 存储值
mData = value;
// 分发值
dispatchingValue(null);
}
}
复制代码
setValue() 是更新 LiveData 值时必然会调用的一个方法,即使是通过 postValue() 更新值,最终也会走这个方法。
LiveData 持有一个版本号字段,用于标识“值的版本”,就像软件版本号一样,这个数字用于判断“当前值是否是最新的”,若版本号小于最新版本号,则表示当前值需要更新。
LiveData 用一个 Object 字段mData
存储了“值”。所以这个值会一直存在&