LiveData 的两重身份(观察者与被观察者)
- 作为观察者,它观察Activity、Fragment的生命周期,只有在active状态下才可能会分发Value;
- 作为被观察者,当它的Value发生变化,对所有观察者分发Value;
注册LiveData监听者源码分析
//Activity类中使用
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
vm.data.observe(this, new Observer<String>() {//进入下面的LiveData.observe
@Override
public void onChanged(String s) {
}
});
}
//LiveData类中
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
if (owner.getLifecycle().getCurrentState() == DESTROYED) {//Activity状态为DESTROYED,则不注册,直接返回
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);//1
......
owner.getLifecycle().addObserver(wrapper);//2
}
- 注释1:将Activity与LiveData观察者observer封装成LifecycleBoundObserver对象;
- 注释2:在这里我们知道,观察Activity生命周期变化的不是LiveData而是LifecycleBoundObserver,当生命周期发生变化会通知LiveData分发Value;
LiveData 同步Value
注册时 的同步Value,关键在于上面的owner.getLifecycle().addObserver(wrapper),**owner.getLifecycle()返回LifecycleRegistry对象 **,其负责维护监听者以及对监听者进行生命周期状态同步;
//LifecycleRegistry类中
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;//监听者初始状态为INITIALIZED,后续会用到,需要注意
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);//封装监听者以及状态
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);//放入map集合
......
sync();//触发生命周期状态同步
......
}
//LifecycleRegistry类中
private void sync() {
......
while (!isSynced()) {
mNewEventOccurred = false;
......
Map.Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {//1
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
private void forwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
mObserverMap.iteratorWithAdditions();
while (ascendingIterator.hasNext() && !mNewEventOccurred) {
Map.Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
ObserverWithState observer = entry.getValue();
......
observer.dispatchEvent(lifecycleOwner, event);//2
......
}
}
//ObserverWithState类中
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = event.getTargetState();
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);//3
mState = newState;
}
- 注释1:mState代表LifecycleRegistry的状态,也就是Activity的状态,因为我们是在onCreate函数对LiveData注册监听的,所以mState为CREATED,newest.getValue().mState表示监听者状态,因为监听者还没有同步过状态,默认为INITIALIZED,所以执行forwardPass();
- 注释2: 分发事件Event,从INITIALIZED到CREATED,所以对应的event是ON_CREATE;
- 注释3:mLifecycleObserver为生命周期的监听者LifecycleBoundObserver类型,触发其onStateChanged函数;
//LifecycleBoundObserver类中
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
if (currentState == DESTROYED) {//如果是DESTROYED状态,则移除监听
removeObserver(mObserver);
return;
}
Lifecycle.State prevState = null;
while (prevState != currentState) {//1
prevState = currentState;
activeStateChanged(shouldBeActive());//2
currentState = mOwner.getLifecycle().getCurrentState();
}
}
//LifecycleBoundObserver类中
boolean shouldBeActive() {//3
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
- 注释1:判断状态是否一致,用while循环,是因为有可能出现跨状态的情况,例如当前Activtiy是RESUMED状态,但监听器是INITIALIZED状态;
- 注释2:触发其父类ObserverWrapper.activeStateChanged函数;
- 注释3:判断Activity是否存于活跃状态;
//ObserverWrapper类中
void activeStateChanged(boolean newActive) {
......
if (mActive) {//1
dispatchingValue(this);//ObserverWrapper是LiveData的内部类,所以调用下面的函数
}
}
//LiveData类中
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);//调用下面的considerNotify函数
initiator = null;
} else {
......
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
//LiveData类中
private void considerNotify(ObserverWrapper observer) {
......
if (observer.mLastVersion >= mVersion) {//2
return;
}
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);//3
}
- 注释1: 这里就是我们常说的,存于活跃状态时 LiveData才会分发Value;
- 注释2: 判断版本,mVersion表示LiveData的版本,默认是-1,当数据发生变化则+1,observer.mLastVersion表示监听器的版本;当对LiveData数据发生修改,那么后注册的监听者在Activity活跃的时候,也能接收到数据,这就是常说的粘性数据,当然,如果注册之前LiveData数据没有修改过,那么就直接return。
数据变化时 的同步Value,当LiveData发生setValue或postValue
//LiveData类中
protected void setValue(T value) {
mVersion++;//LiveData版本号+1
mData = value;
dispatchingValue(null);//调用下面的函数分发Value
}
//LiveData类中
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
......
} else {
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());//1
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
- 代码是否似曾相识,没错,跟注册时的同步Value一样,都走到dispatchingValue函数,只不过这次走的是else分支,遍历所有监听器进行分发。
LiveData 的不可变性
下面代码,为了控制MutableLiveData的修改权限收敛在vm内部,只保留不可以修改的LiveData,防止修改发散出现不可预知的情况。
class MyViewModel : ViewModel() {
private val _data = MutableLiveData<String>()
val data: LiveData<String> = _data//只保留只有访问权限的LiveData
}
LiveData 去掉粘性
注册LiveData监听时,通过反射将监听者与LiveData的版本对齐,就可以避免收到粘性数据,网上有很多例子,这里就不展开了;
LiveData postValue 可能会数据丢失
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;//1
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);//2
}
private final Runnable mPostValueRunnable = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;//3
mPendingData = NOT_SET;
}
setValue((T) newValue);
}
};
- 注释1:子线程执行postValue,mPendingData默认值为NOT_SET,所以postTask为true;
- 注释2:ArchTaskExecutor.getInstance().postToMainThread 往主线程post setValue任务;
- 注释3:任务核心,将新值newValue通过setValue分发出去,把mPendingData重置;
- 因为postTask 变量的存在,执行postValue函数(生产者)在Runnable任务(消费者)没有处理完之前是会直接true的,当执行生产者速度比消费者快,可能会出现数据丢失,。例如,子线程连续执行postValue(1)、postValue(2),当postValue(1)对应的Runnable没有执行完,此时mPendingData值为1,接着立马触发postValue(2),因为mPendingData值为1,导致postTask为false,所以postValue函数就直接true了,postValue(2)这条数据就丢失了。
LiveData的思考
- 适用场景:数据驱动的场景,也叫事件驱动,例如当List集合数据发生变化,同步给多个监听者;
- 不适用场景:生产者速度比消费速度快的场景,例如文件下载进度更新;
- 不适用场景:状态同步场景,例如Activity通过vm的LiveData驱动Fragment toast消息,那么当Fragment关闭再次弹起,也会收到这个粘性回调。
涉及类
- MutableLiveData类继承LiveData,遵循最小知识原则,只提供setValue\postValue等几个接口;
- LiveData类维护版本、监听者集合、负责Value的分发;
- ObserverWrapper类,负责通知LiveData监听者数据有变化;
- LifecycleBoundObserver类继承ObserverWrapper,封装Activity、Fragment+LiveData监听者,它才是监听生命周期变化的核心,当生命周期发生变化 通知LiveData监听者数据有变化;
- AlwaysActiveObserver类继承ObserverWrapper,对比LifecycleBoundObserver,它不做生命周期监听,只要数据有变化,则通知LiveData监听者数据有变;
- LifecycleRegistry,负责维护生命周期监听者以及做生命周期同步;
总结
- LiveData适合用在数据驱动的场景,因为其粘性问题,所以不适合状态驱动的场景;
- 暴露不可修改的LiveData,对其修改权限进行控制。
以上分析有不对的地方,请指出,互相学习,谢谢哦!