LiveData 在项目中时常用到,但是对其源码解读不深,所以深入了解一下。
MutableLiveData<Integer> intLiveData = new MutableLiveData<>();
intLiveData.setValue(12);
intLiveData.observe(this, integer -> {
Log.d("Main", "integer " + integer);
});
上面是LiveData的普通用法,根据用法来追踪代码实现。
MutableLiveData 的实现:
public class MutableLiveData<T> extends LiveData<T> {
@Override
public void postValue(T value) {
super.postValue(value);
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
重写了 LiveData 的 postValue 和 setValue 方法,在LiveData中这两个方法是 protected 修饰的,所以外部无法直接调用。
LiveData 虽然有abstract修饰,但是并没有一个抽象方法需要它的子类去实现,感觉很奇怪。
setValue() 的实现
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
这个方法被声明要在主线程调用,子线程中可以通过 postValue() 来修改,这个后面再讲。
- assertMainThread 这个方法用于判断当前线程是否为主线程,实现方式是 Looper.getMainLooper.getThread == Thread.currentThread()
- mVersion 记录LiveData.mData被修改次数
- mData是LiveData中实际保存的值
- dispatchingValue() 通知观察者,LiveData 的值发生了变化
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;
}
通过上面的方法知道 initiator 为 null. 所以会走 else . mObservers 是一个SafeIterableMap对象,看命名就知道是遍历安全的Map. 内部是一个 WeakHashMap, 本身实现了 Iterable 接口。
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;
//noinspection unchecked
observer.mObserver.onChanged((T) mData);
}
到这一步需要说一下,可以讲 ObserverWrapper 看成一个观察者。
- 那么观察者再被通知前,要做两个判断。一个是 mActive 判断,就是当前观察者是否是活的状态;另一个是对当前状态的再次确认。
- 当这两个条件都满足之后再判断 观察者上次变动的 version 如果大于等于当前更新的 version 则不更新。
- 执行更新操作。
总结
上述过程是LiveData.setValue()后的代码逻辑,其实就是观察者模式,只不过观察者再被通知前做了一些判断。接下来会就是观察者的实现。
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);
}
- 一般都会在 Activity 和 Fragment 中调用 observe 方法,所以传递的 LifecycleOwner 就是当前 Activity/Fragment. 然后就是判断是否销毁,如果销毁则直接 return
- 创建 LifecycleBoundObserver 观察者对象并 put 到 mObservers 中。
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@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(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
- 这个类实现了 LifecycleEventObserver 接口,也就是说,当LifecycleOwner生命周期变化时它会收到通知。‘
- 在onStateChanged方法中,如果当前组件生命周期执行到 DESTROYED , 那么就会把当前观察者移除。不然的话就会调用 activeStateChanged() 方法,这个方法在父类 ObserverWrapper 中定义。
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
boolean wasInactive = LiveData.this.mActiveCount == 0;
LiveData.this.mActiveCount += mActive ? 1 : -1;
if (wasInactive && mActive) {
onActive();
}
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive();
}
if (mActive) {
dispatchingValue(this);
}
}
这个方法比较简单,先判断状态是否变化,变化后更新状态,如果新状态是 active 那么还会调用 dispatchingValue() 去通知观察者值发生了变化。方法中参数是当前观察者,那么就不会从 mObservers 中遍历取所有的观察者,而是直接更新当前观察者。
observeForever()
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
assertMainThread("observeForever");
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && existing instanceof LiveData.LifecycleBoundObserver) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
wrapper.activeStateChanged(true);
}
LiveData还有一个 observeForever 方法,这个方法是说只要值变化,就通知我,不需要判断生命周期变化。其实内部实现也简单。
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer<? super T> observer) {
super(observer);
}
@Override
boolean shouldBeActive() {
return true;
}
}
wrapper.activeStateChanged(true) 和对 shouldBeActive 的重写,导致观察者的拦截条件都不成立,所以会一直通知。
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 为要更新的值并通过 ArchTaskExecutor 进行更新
@Override
public void postToMainThread(Runnable runnable) {
mDelegate.postToMainThread(runnable);
}
在 ArchTaskExecutor 中调用代理类的 postToMainThread(). mDelegate 是一个 DefaultTaskExecutor 对象。
@Override
public void postToMainThread(Runnable runnable) {
if (mMainHandler == null) {
synchronized (mLock) {
if (mMainHandler == null) {
mMainHandler = new Handler(Looper.getMainLooper());
}
}
}
//noinspection ConstantConditions
mMainHandler.post(runnable);
}
DefaultTaskExecutor.postToMainThread() 内部是通过 MainHandler 实现的。在回到LiveData中的runnable参数
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue);
}
};
总结
到这 LiveData 就整体就了解了,拆分成观察者和被观察者可以更方便的理解 LiveData 的设计。