LiveData 源码分析

_(:з」∠)_ 流水账一篇
注:本文所有代码基于 android.arch.lifecycle 1.0.0-alpha1

Lifecycle-aware Components 源码分析 一文中,我们已经分析了 Lifecycle 框架中所有的 lifecyle 事件产生流程以及分发流程。本文将会基于这部分知识来分析 Lifecycle 框架中的 LiveData 组件。

提出问题

结合 LiveData javadoc, LiveData 文档,我们可以了解到 LiveData 主要作用是数据发生变化时通知 Observer,那么 LiveData 是如何实现这部分内容的呢?

LiveData

observe

有监听得先有注册,先来看 observe 方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@MainThread
public void observe(LifecycleOwner owner, Observer<T> 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,紧接着调用了 LifecycleBoundObserveractiveStateChanged 方法。

LifecycleBoundObserver

接着看 LifecycleBoundObserver

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class LifecycleBoundObserver implements LifecycleObserver {
public final LifecycleOwner owner;
public final Observer<T> observer;
public boolean active;
public int lastVersion = START_VERSION;
LifecycleBoundObserver(LifecycleOwner owner, Observer<T> 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 的状态处于 STARTEDRESUMED 时,传入 activeStateChanged 的值为 true,即 LifecycleBoundObserver 会被标记为激活状态,同时会增加 LiveDatamActiveCount 计数。接着可以看到,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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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<Map.Entry<Observer<T>, LifecycleBoundObserver>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}

其中 mDispatchingValue, mDispatchInvalidated 只在 dispatchingValue 方法中使用,显然这两个变量是为了防止重复分发相同的内容。

considerNotify

接下来,无论哪个路径都会调用 considerNotify

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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:

1
2
private static final Object NOT_SET = new Object();
private Object mData = NOT_SET;

可能会有人担心当 LiveDatamData 未发生变更时,第一次调用 observe 会将 NOT_SET 传递到 Observer 中。事实上并不会,因为 LiveDatamVersionLifecycleBoundObserverlastVersion 的默认值均为 START_VERSION

1
2
3
4
5
6
7
8
9
10
11
12
public abstract class LiveData<T> {
...
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

1
2
3
4
5
6
7
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}

setValueobserve 方法一样均需要在主线程上执行,当 setValue 的时候 mVersion 的值会自增,并通知 Observer 数据发生变化。

postValue

setValue 还有另一个替代的方法 postValue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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 可以运行在任意线程上,而 ObserverOnChange 回调会执行在主线程上。

observeForever

最后再看下 observeForever

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@MainThread
public void observeForever(Observer<T> 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;
}
};

可以看到,observeForeverObserver 注册了在一个永远处于 RESUMED 的 LifecycleOwner 中,所以通过 observeForever 注册的 Observer 需要通过 removeObserver 来取消数据变化的监听。

总结

至此,我们已经明白 LiveData 主要是通过 LifecycleBoundObserverLifecycle 结合来控制数据的分发。

LiveData 的代码比 Lifecycle 要简单得多,主要是有了 Lifecycle 部分的分析作为基础,看起来很轻松。因为简单,所以文章记录的时候流水账比较严重,本来不打算发的 _(:з」∠)_ 不过写都写了,扔出来占个位置吧。