寫在前面
在上一篇文章Android架構組件(Architecture Components)之 Lifecycle詳解中,說到了要想了解LiveData,需要先了解Lifecycle。所以這次就開始來講講LiveData了。希望還沒看過的朋友先看下上一篇文章,因為這篇文章會有一些依賴到上一篇文章的。
LiveData
結構
先來看看LiveData的結構:
LiveData其實是一個抽象類,但它的內部并沒有抽象的方法。我們可以通過MutableLiveData來使用它。它的實現僅僅只是將setValue()
和postValue()
方法設置為public。所以重點還是應該來分析LiveData。除此之外,LiveData還有幾個內部類:
和LifecycleRegistry一樣,LiveData內部也維護著一個觀察者列表:mObservers
,它的類型是SafeIterableMap<Observer<? super T>, ObserverWrapper>
,對應存儲的值是ObserverWrapper,用了裝飾器模式將Observer給包裝起來。為什么要將Observer包裝起來呢?這是因為LiveData允許我們有兩種不同的觀察模式:有生命周期限制的觀察者和一直觀察的觀察者,分別對應著它的兩個子類: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);
}
首先要確保該方法是在主線程上調用的,否則會直接拋出異常。接著判斷如果依附的LifecycleOwner目前已經是DESTROYED
狀態的話,就直接返回了。緊接著將方法傳入的Observer和LifecycleOwner封裝成一個LifecycleBoundObserver添加到隊列中。最后向LifecycleOwner中注冊了一個觀察者。到這里為止,有了觀察者和被觀察者,整套機制就能運轉起來了。
上一篇文章的最后,講到了dispatchEvent()
方法就結束了,再來回顧一下:
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
當時說了:
LifecycleObserver是一個LifecycleEventObserver,也是一個接口來著,繼承了LifecycleObserver
結合上面的類圖,LifecycleBoundObserver不僅是繼承了ObserverWrapper,它還實現了LifecycleEventObserver接口。所以當LifecycleOwner的狀態發生變化時,會走到LifecycleBoundObserver的onStateChanged()
方法中:
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
如果生命周期的狀態變成了DESTROYED
,LiveData會自動幫我們移除掉觀察者,避免內存泄漏。
shouldBeActive()
是一個抽象方法,來看下它的兩個子類的不同。
// LifecycleBoundObserver
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
// AlwaysActiveObserver
@Override
boolean shouldBeActive() {
return true;
}
LifecycleBoundObserver中,只有當前的狀態至少處于STARTED
的才會被認為是活躍的。而AlwaysActiveObserver由于沒有生命周期的概念,所以一直是處于活躍的狀態的。這是它們的區別所在。
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是否應該處于活躍狀態,如果是的話,才去更新數據。這里又看到了熟悉的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;
}
重點在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);
}
在這里會最后一次去檢查Observer是否處于激活狀態,并且目前的新的數據版本是否比當前高,條件都滿足的話就會通知Observer更新數據了。
observeForever()
除了observe()
方法外,還有一個observeForever()
方法。這個比較簡單,就是普通的觀察者模式。使用這個方法,一定要注意,要在恰當的時機,通過removeObserver()
或者removeObservers()
將觀察者移除掉,否則很可能會發生內存泄漏。
setValue()
通過LifecycleOwner的生命周期變化來決定是否要通知觀察者,這只是LiveData通知觀察者的一種方式。當數據發生變化時,LiveData也會通知觀察者。
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
當數據發生變化時,會更新版本號,然后又是調用了dispatchingValue()
,流程還是和上面的一樣,就不再講下去了。
postValue()
上面的setValue()
要求在主線程中調用,如果是在子線程想更新數據的話,可以使用這個方法。
寫在最后
和上一篇的LifecycleOwner結合起來,總算是把這套加入生命周期的觀察者模式給理清了。剩下的就差ViewModel還沒有分析了。