前言
在 Lifecycle-aware Components 源碼分析 一文中考阱,我們已經(jīng)分析了 Lifecycle 框架中所有的 lifecyle 事件產(chǎn)生流程以及分發(fā)流程。本文將會基于這部分知識來分析 Lifecycle 框架中的 LiveData 組件。
提出問題
結(jié)合 LiveData javadoc, LiveData 文檔匀归,我們可以了解到 LiveData 主要作用是數(shù)據(jù)發(fā)生變化時通知 Observer食店,那么 LiveData 是如何實現(xiàn)這部分內(nèi)容的呢罪郊?
LiveData
observe
有監(jiān)聽得先有注冊,先來看 observe 方法:
@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 方法需運行在主線程中梢灭,執(zhí)行時會將 Observer 傳入 LifecycleBoundObserver,并將 LifecycleBoundObserver 通過 addObserver 注冊至 Lifecycle蒸其,緊接著調(diào)用了 LifecycleBoundObserver 的 activeStateChanged 方法敏释。
LifecycleBoundObserver
接著看 LifecycleBoundObserver:
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 事件。當(dāng) LifecycleOwner 的狀態(tài)處于 STARTED 或 RESUMED 時摸袁,傳入 activeStateChanged 的值為 true钥顽,即 LifecycleBoundObserver 會被標(biāo)記為激活狀態(tài),同時會增加 LiveData 的 mActiveCount 計數(shù)靠汁。接著可以看到蜂大,onActive 會在 mActiveCount 為 1 時觸發(fā),onInactive 方法則只會在 mActiveCount 為 0 時觸發(fā)蝶怔。這里就與 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 處于激活狀態(tài)添谊,則會調(diào)用 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<Map.Entry<Observer<T>, LifecycleBoundObserver>> iterator =
? ? ? ? ? ? ? ? ? mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
? ? ? ? ? ? ? considerNotify(iterator.next().getValue());
? ? ? ? ? ? ? if (mDispatchInvalidated) {
? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? }
? ? ? ? ? }
? ? ? }
? } while (mDispatchInvalidated);
? mDispatchingValue = false;
}
其中 mDispatchingValue, mDispatchInvalidated 只在 dispatchingValue 方法中使用财喳,顯然這兩個變量是為了防止重復(fù)分發(fā)相同的內(nèi)容。
considerNotify
接下來,無論哪個路徑都會調(diào)用 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) {
? ? ? // 數(shù)據(jù)已經(jīng)是最新
? ? ? return;
? }
? observer.lastVersion = mVersion;
? //noinspection unchecked
? observer.observer.onChanged((T) mData);
}
注:mVersion 代表的是數(shù)據(jù)變化的次數(shù)耳高,下文會補充說明扎瓶。
顯然 considerNotify 的作用就是通知處于激活狀態(tài)且數(shù)據(jù)未更新的 Observer 數(shù)據(jù)已發(fā)生變化。
其中 mData 即是 LiveData 當(dāng)前的數(shù)據(jù)泌枪,默認(rèn)是一個全局 Object:
private static final Object NOT_SET = new Object();
private Object mData = NOT_SET;
可能會有人擔(dān)心當(dāng) LiveData 的 mData 未發(fā)生變更時概荷,第一次調(diào)用 observe 會將 NOT_SET 傳遞到 Observer 中。事實上并不會碌燕,因為 LiveData 的 mVersion 和 LifecycleBoundObserver 的 lastVersion 的默認(rèn)值均為 START_VERSION:
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 判斷時就會直接返回而不執(zhí)行 observer.observer.onChanged((T) mData)误证。
setValue
再來看 setValue:
@MainThread
protected void setValue(T value) {
? assertMainThread("setValue");
? mVersion++;
? mData = value;
? dispatchingValue(null);
}
setValue 與 observe 方法一樣均需要在主線程上執(zhí)行,當(dāng) setValue 的時候 mVersion 的值會自增修壕,并通知 Observer 數(shù)據(jù)發(fā)生變化愈捅。
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 回調(diào)會執(zhí)行在主線程上蓝谨。
observeForever
最后再看下 observeForever:
@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;
? }
};
可以看到,observeForever 將 Observer 注冊了在一個永遠(yuǎn)處于 RESUMED 的 LifecycleOwner 中青团,所以通過 observeForever 注冊的 Observer 需要通過 removeObserver 來取消數(shù)據(jù)變化的監(jiān)聽譬巫。
總結(jié)
至此,我們已經(jīng)明白 LiveData 主要是通過 LifecycleBoundObserver 與 Lifecycle 結(jié)合來控制數(shù)據(jù)的分發(fā)督笆。
LiveData 的代碼比 Lifecycle 要簡單得多芦昔,主要是有了 Lifecycle 部分的分析作為基礎(chǔ),看起來很輕松娃肿。
附《Android核心知識筆記2020》分享
前段時間我和圈子里的幾位架構(gòu)師朋友一起閑聊時的突發(fā)奇想咕缎,我們在學(xué)習(xí)Android開發(fā)的時候或多或少也受到了一些前輩的指導(dǎo),所以想把這份情懷延續(xù)下去咸作。三個月后锨阿,這套資料就出來了,需要這份資料的朋友加Android學(xué)習(xí)交流群1049273031即可獲取记罚。