前言
在 Lifecycle-aware Components 源码分析 一文中,我们已经分析了 Lifecycle 框架中所有的 lifecyle 事件产生流程以及分发流程。本文将会基于这部分知识来分析 Lifecycle 框架中的 LiveData 组件。
提出问题
结合 LiveData javadoc, LiveData 文档,我们可以了解到 LiveData 主要作用是数据发生变化时通知 Observer,那么 LiveData 是如何实现这部分内容的呢?
LiveData
observe
有监听得先有注册,先来看 observe 方法:
@MainThread
public void observe(LifecycleOwner owner, Observer
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
LifecycleBoundObserver existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && existing.owner != wrapper.owner) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
owner.getLifecycle().addObserver(wrapper);
wrapper.activeStateChanged(isActiveState(owner.getLifecycle().getCurrentState()));
}
observe 方法需运行在主线程中,执行时会将 Observer 传入 LifecycleBoundObserver,并将 LifecycleBoundObserver 通过 addObserver 注册至 Lifecycle,紧接着调用了 LifecycleBoundObserver 的 activeStateChanged 方法。
LifecycleBoundObserver
接着看 LifecycleBoundObserver:
class LifecycleBoundObserver implements LifecycleObserver {
public final LifecycleOwner owner;
public final Observer
public boolean active;
public int lastVersion = START_VERSION;
LifecycleBoundObserver(LifecycleOwner owner, Observer
this.owner = owner;
this.observer = observer;
}
@SuppressWarnings("unused")
@OnLifecycleEvent(Lifecycle.Event.ON_ANY)
void onStateChange() {
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(observer);
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
activeStateChanged(isActiveState(owner.getLifecycle().getCurrentState()));
}
void activeStateChanged(boolean newActive) {
if (newActive == active) {
return;
}
active = newActive;
boolean wasInactive = LiveData.this.mActiveCount == 0;
LiveData.this.mActiveCount += active ? 1 : -1;
if (wasInactive && active) {
onActive();
}
if (LiveData.this.mActiveCount == 0 && !active) {
onInactive();
}
if (active) {
dispatchingValue(this);
}
}
}
static boolean isActiveState(State state) {
return state.isAtLeast(STARTED);
}
不难看出 onStateChange 会接收所有的 lifecycle 事件。当 LifecycleOwner 的状态处于 STARTED 或 RESUMED 时,传入 activeStateChanged 的值为 true,即 LifecycleBoundObserver 会被标记为激活状态,同时会增加 LiveData 的 mActiveCount 计数。接着可以看到,onActive 会在 mActiveCount 为 1 时触发,onInactive 方法则只会在 mActiveCount 为 0 时触发。这里就与 LiveData javadoc 所描述的完全吻合(In addition, LiveData has onActive() and onInactive() methods to get notified when number of active Observers change between 0 and 1. This allows LiveData to release any heavy resources when it does not have any Observers that are actively observing.)。
dispatchingValue
此后,如果 LifecycleBoundObserver 处于激活状态,则会调用 dispatchingValue:
private void dispatchingValue(@Nullable LifecycleBoundObserver initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
for (Iterator
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
其中 mDispatchingValue, mDispatchInvalidated 只在 dispatchingValue 方法中使用,显然这两个变量是为了防止重复分发相同的内容。
considerNotify
接下来,无论哪个路径都会调用 considerNotify:
private void considerNotify(LifecycleBoundObserver observer) {
if (!observer.active) {
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 (!isActiveState(observer.owner.getLifecycle().getCurrentState())) {
return;
}
if (observer.lastVersion >= mVersion) {
// 数据已经是最新
return;
}
observer.lastVersion = mVersion;
//noinspection unchecked
observer.observer.onChanged((T) mData);
}
注:mVersion 代表的是数据变化的次数,下文会补充说明。
显然 considerNotify 的作用就是通知处于激活状态且数据未更新的 Observer 数据已发生变化。
其中 mData 即是 LiveData 当前的数据,默认是一个全局 Object:
private static final Object NOT_SET = new Object();
private Object mData = NOT_SET;
可能会有人担心当 LiveData 的 mData 未发生变更时,第一次调用 observe 会将 NOT_SET 传递到 Observer 中。事实上并不会,因为 LiveData 的 mVersion 和 LifecycleBoundObserver 的 lastVersion 的默认值均为 START_VERSION:
public abstract class LiveData
...
static final int START_VERSION = -1;
private int mVersion = START_VERSION;
...
class LifecycleBoundObserver implements LifecycleObserver {
...
public int lastVersion = START_VERSION;
...
}
...
}
在 observer.lastVersion >= mVersion 判断时就会直接返回而不执行 observer.observer.onChanged((T) mData)。
setValue
再来看 setValue:
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
setValue 与 observe 方法一样均需要在主线程上执行,当 setValue 的时候 mVersion 的值会自增,并通知 Observer 数据发生变化。
postValue
setValue 还有另一个替代的方法 postValue:
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
AppToolkitTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue);
}
};
其中 AppToolkitTaskExecutor 是通过一个以 Main Looper 作为 Looper 的 Handler 将 mPostValueRunnable 运行在主线程上,所以 postValue 可以运行在任意线程上,而 Observer 的 OnChange 回调会执行在主线程上。
observeForever
最后再看下 observeForever:
@MainThread
public void observeForever(Observer
observe(ALWAYS_ON, observer);
}
private static final LifecycleOwner ALWAYS_ON = new LifecycleOwner() {
private LifecycleRegistry mRegistry = init();
private LifecycleRegistry init() {
LifecycleRegistry registry = new LifecycleRegistry(this);
registry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
registry.handleLifecycleEvent(Lifecycle.Event.ON_START);
registry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
return registry;
}
@Override
public Lifecycle getLifecycle() {
return mRegistry;
}
};
可以看到,observeForever 将 Observer 注册了在一个永远处于 RESUMED 的 LifecycleOwner 中,所以通过 observeForever 注册的 Observer 需要通过 removeObserver 来取消数据变化的监听。
总结
至此,我们已经明白 LiveData 主要是通过 LifecycleBoundObserver 与 Lifecycle 结合来控制数据的分发。
LiveData 的代码比 Lifecycle 要简单得多,主要是有了 Lifecycle 部分的分析作为基础,看起来很轻松。
附《Android核心知识笔记2020》分享
前段时间我和圈子里的几位架构师朋友一起闲聊时的突发奇想,我们在学习Android开发的时候或多或少也受到了一些前辈的指导,所以想把这份情怀延续下去。三个月后,这套资料就出来了,需要这份资料的朋友加Android学习交流群1049273031即可获取。