LiveData源码,我们直接通过Observe方法开始分析:
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
owner.getLifecycle().addObserver(wrapper);
}
主要做了两件事情,生成LifecycleBoundObserver,添加自己内部SafeIterableMap中,然后调用Observer方法完成对owner的监听。
我们看下LifecycleBoundObserver源码:
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
if (currentState == DESTROYED) {
removeObserver(mObserver);
return;
}
Lifecycle.State prevState = null;
while (prevState != currentState) {
prevState = currentState;
activeStateChanged(shouldBeActive());
currentState = mOwner.getLifecycle().getCurrentState();
}
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<? super T> observer) {
mObserver = observer;
}
abstract boolean shouldBeActive();
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
void detachObserver() {
}
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
changeActiveCounter(mActive ? 1 : -1);
if (mActive) {
dispatchingValue(this);
}
}
}
我们主要看下onStateChanged()方法,这里监听LifecycleOwner生命周期,当变化时,刷新LiveData活动状态。
我们继续看下setVaule()方法,
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
判断是否子啊主线程,调用了dispatchingValue()方法:
@SuppressWarnings("WeakerAccess") /* synthetic access */
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
继续调用了considerNotify()方法,
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
// Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
//
// we still first check observer.active to keep it as the entrance for events. So even if
// the observer moved to an active state, if we've not received that event, we better not
// notify for a more predictable notification order.
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
}
这个没啥好说的,调用observer接口更新数据,而observer是一开始我们在Observer()方法中传入进去的。
LiveData能够感知到生命周期,会将数据更新到激活的组件中。这样的话,也会发生一些问题
1.postValue数据丢失的问题
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
通过上面的源码分析:postValue 只是把传进来的数据先存到 mPendingData,然后往主线程抛一个 Runnable,在这个 Runnable 里面再调用 setValue 来把存起来的值真正设置上去,并回调观察者们。而如果在这个 Runnable 执行前多次 postValue,其实只是改变暂存的值 mPendingData,并不会再次抛另一个 Runnable。这就会出现后设置的值把前面的值覆盖掉的问题,会导致事件丢失。
解决思路:
第一种:我们自己切换到MainThread用setValue()方法;
第二种:我们可以再封装一层,内部使用Handler来解决;
2.setValue不回调观察者
LiveData 的生命周期感知能力就体现在这里,它不会回调处于「非激活状态」(即 onStart 之后到 onPause 之前)的观察者,因为这时更新 View 没有意义,而且比较危险,它会等到观察者激活之后再把新的值回调给他。
但是如果我传了多个数据(假设都是用 setValue 保证不会被覆盖),那些处于非激活状态的观察者是毫不知情的,他们在激活的时候只会收到最后一个数据。这对于事件传递来说,就表现为事件丢失,中间传的任何数据都无法收到,那也就失去了事件传递的意义。
解决思路:
我们可以自己打造一个LiveEventObserver,在其内部新建一个List保存未激活状态时发送的消息,当处于活跃状态时,再轮询发送消息。
3.LiveData数据倒灌问题
LiveData存在的这个问题对于Google官方的设计者来说并不算是一个缺陷,只是对于使用者来说这种功能不太“好”,其原因就是当LiveData每次改变时,即调用setValue时,LiveData对应当version就会从-1自增,但是新监听LiveData的Observer对应的version就会从-1开始,调用observe时内部会判断监听者的version是否小于LiveData的version,很明显当LiveData前面已经修改过之后,其version>-1,监听者的version为-1,这个判断条件判断成立,就会马上把LiveData的值返回给监听者。
解决思路:
我这里只介绍其中一种方法,即UnPeekLiveData
其思路也很清晰,为每个传入的observer对象携带一个布尔类型的值,作为其是否能进入observe方法的开关。每当有一个新的observer存进来的时候,开关默认关闭。
每次setValue后,打开所有Observer的开关,允许所有observe执行。
同时方法进去后,关闭当前执行的observer开关,即不能对其第二次执行了,除非你重新setValue。
更多解决方案看这里https://www.jianshu.com/p/d0244c4c7cc9
网友评论