寫在前面
在上一篇文章Android架構(gòu)組件(Architecture Components)之 Lifecycle詳解中诅挑,說到了要想了解LiveData夫嗓,需要先了解Lifecycle。所以這次就開始來講講LiveData了篙挽。希望還沒看過的朋友先看下上一篇文章荆萤,因?yàn)檫@篇文章會(huì)有一些依賴到上一篇文章的。
LiveData
結(jié)構(gòu)
先來看看LiveData的結(jié)構(gòu):
LiveData其實(shí)是一個(gè)抽象類铣卡,但它的內(nèi)部并沒有抽象的方法链韭。我們可以通過MutableLiveData來使用它。它的實(shí)現(xiàn)僅僅只是將setValue()
和postValue()
方法設(shè)置為public煮落。所以重點(diǎn)還是應(yīng)該來分析LiveData敞峭。除此之外,LiveData還有幾個(gè)內(nèi)部類:
和LifecycleRegistry一樣蝉仇,LiveData內(nèi)部也維護(hù)著一個(gè)觀察者列表:mObservers
旋讹,它的類型是SafeIterableMap<Observer<? super T>, ObserverWrapper>
,對(duì)應(yīng)存儲(chǔ)的值是ObserverWrapper轿衔,用了裝飾器模式將Observer給包裝起來沉迹。為什么要將Observer包裝起來呢?這是因?yàn)長(zhǎng)iveData允許我們有兩種不同的觀察模式:有生命周期限制的觀察者和一直觀察的觀察者害驹,分別對(duì)應(yīng)著它的兩個(gè)子類:LifecycleBoundObserver和AlwaysActiveObserver鞭呕。兩種不同的方式供我們選擇,給我們帶來了很高的靈活性宛官。
observe()
回到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);
}
首先要確保該方法是在主線程上調(diào)用的摘刑,否則會(huì)直接拋出異常进宝。接著判斷如果依附的LifecycleOwner目前已經(jīng)是DESTROYED
狀態(tài)的話,就直接返回了枷恕。緊接著將方法傳入的Observer和LifecycleOwner封裝成一個(gè)LifecycleBoundObserver添加到隊(duì)列中党晋。最后向LifecycleOwner中注冊(cè)了一個(gè)觀察者。到這里為止,有了觀察者和被觀察者未玻,整套機(jī)制就能運(yùn)轉(zhuǎn)起來了灾而。
上一篇文章的最后,講到了dispatchEvent()
方法就結(jié)束了扳剿,再來回顧一下:
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
當(dāng)時(shí)說了:
LifecycleObserver是一個(gè)LifecycleEventObserver旁趟,也是一個(gè)接口來著,繼承了LifecycleObserver
結(jié)合上面的類圖庇绽,LifecycleBoundObserver不僅是繼承了ObserverWrapper锡搜,它還實(shí)現(xiàn)了LifecycleEventObserver接口。所以當(dāng)LifecycleOwner的狀態(tài)發(fā)生變化時(shí)瞧掺,會(huì)走到LifecycleBoundObserver的onStateChanged()
方法中:
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
如果生命周期的狀態(tài)變成了DESTROYED
,LiveData會(huì)自動(dòng)幫我們移除掉觀察者耕餐,避免內(nèi)存泄漏。
shouldBeActive()
是一個(gè)抽象方法辟狈,來看下它的兩個(gè)子類的不同肠缔。
// LifecycleBoundObserver
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
// AlwaysActiveObserver
@Override
boolean shouldBeActive() {
return true;
}
LifecycleBoundObserver中,只有當(dāng)前的狀態(tài)至少處于STARTED
的才會(huì)被認(rèn)為是活躍的哼转。而AlwaysActiveObserver由于沒有生命周期的概念明未,所以一直是處于活躍的狀態(tài)的。這是它們的區(qū)別所在壹蔓。
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);
}
}
這里主要是判斷Observer是否應(yīng)該處于活躍狀態(tài)趟妥,如果是的話,才去更新數(shù)據(jù)佣蓉。這里又看到了熟悉的dispatchXXX()
方法煮纵。
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;
}
重點(diǎn)在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;
//noinspection unchecked
observer.mObserver.onChanged((T) mData);
}
在這里會(huì)最后一次去檢查Observer是否處于激活狀態(tài),并且目前的新的數(shù)據(jù)版本是否比當(dāng)前高偏螺,條件都滿足的話就會(huì)通知Observer更新數(shù)據(jù)了行疏。
observeForever()
除了observe()
方法外,還有一個(gè)observeForever()
方法套像。這個(gè)比較簡(jiǎn)單酿联,就是普通的觀察者模式。使用這個(gè)方法夺巩,一定要注意贞让,要在恰當(dāng)?shù)臅r(shí)機(jī),通過removeObserver()
或者removeObservers()
將觀察者移除掉柳譬,否則很可能會(huì)發(fā)生內(nèi)存泄漏喳张。
setValue()
通過LifecycleOwner的生命周期變化來決定是否要通知觀察者,這只是LiveData通知觀察者的一種方式美澳。當(dāng)數(shù)據(jù)發(fā)生變化時(shí)销部,LiveData也會(huì)通知觀察者摸航。
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
當(dāng)數(shù)據(jù)發(fā)生變化時(shí),會(huì)更新版本號(hào)舅桩,然后又是調(diào)用了dispatchingValue()
,流程還是和上面的一樣酱虎,就不再講下去了。
postValue()
上面的setValue()
要求在主線程中調(diào)用擂涛,如果是在子線程想更新數(shù)據(jù)的話读串,可以使用這個(gè)方法。
寫在最后
和上一篇的LifecycleOwner結(jié)合起來撒妈,總算是把這套加入生命周期的觀察者模式給理清了恢暖。剩下的就差ViewModel還沒有分析了。