本文首發於微信公衆號「後廠村碼農」html
在上一篇文章中咱們學習了LiveData的基本用法,咱們知道LiveData是一個可觀察的數據持有者,他是具備組件生命週期感知的,那麼它是如何觀察組件生命週期變化的呢?LiveData和RxJava的不一樣的是,LiveData並非通知全部觀察者,它只會通知處於Active狀態的觀察者,若是一個觀察者處於DESTROYED狀態,它將不會收到通知,這一點又是如何作到的?還有另一點,Transformations的map方法其內部進行了什麼操做?等等問題,會在這篇文章中給你們進行講解。前端
經過調用LiveData的observe方法來註冊觀察者,LiveData的observe方法以下所示。 frameworks/support/lifecycle/livedata-core/src/main/java/androidx/lifecycle/LiveData.javajava
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
//若是被觀察者的當前的狀態是DESTROYED,就return
if (owner.getLifecycle().getCurrentState() == DESTROYED) {//1
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);//2
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);//3
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);//4
}
複製代碼
註釋1處的owner實際上就是註冊時傳進來來組件,好比Activity,獲取組件當前的狀態,若是狀態爲DESTROYED,那麼直接return,這說明DESTROYED狀態的組件是不容許註冊的。android
若是你還不瞭解Lifecycle的狀態,能夠查看Android Jetpack架構組件(三)帶你瞭解Lifecycle(原理篇)這篇文章。 註釋2處新建了一個LifecycleBoundObserver包裝類,將owner和observer傳了進去。 註釋3處將observer和LifecycleBoundObserver存儲到SafeIterableMap<Observer<? super T>, ObserverWrapper>mObservers
中,putIfAbsent方法和put方法有區別,若是傳入key對應的value已經存在,就返回存在的value,不進行替換。若是不存在,就添加key和value,返回null。 若是等於null,在註釋4處會將LifecycleBoundObserver添加到Lifecycle中完成註冊,這樣當咱們調用LiveData的observe方法時,其實是LiveData內部完成了Lifecycle的觀察者的添加,這樣LiveData天然也就有了觀察組件生命週期變化的能力。程序員
LifecycleBoundObservers是LiveData的內部類,代碼以下所示。 frameworks/support/lifecycle/livedata-core/src/main/java/androidx/lifecycle/LiveData.java微信
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@NonNull final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);//1
return;
}
activeStateChanged(shouldBeActive());//2
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
複製代碼
LifecycleBoundObserver繼承了ObserverWrapper類,重寫了shouldBeActive方法,用於判斷當前傳入的組件的狀態是不是Active的,Active狀態包括STARTED和RESUMED狀態。架構
LifecycleBoundObserver實現了GenericLifecycleObserver接口,當組件狀態發生變化時,會調用onStateChanged方法,當組件處於DESTROYED狀態時,會調用註釋1處的removeObserver方法,來移除observer。 這樣在文章開頭的疑問就解決了,爲何一個觀察者(組件)處於DESTROYED狀態時,它將不會收到通知。app
接着會調用註釋2處的activeStateChange方法,代碼以下所示。ide
frameworks/support/lifecycle/livedata-core/src/main/java/androidx/lifecycle/LiveData.javapost
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<? super T> observer) {
mObserver = observer;
}
abstract boolean shouldBeActive();
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
void detachObserver() {
}
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
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);//1
}
}
}
複製代碼
activeStateChanged方法定義在抽象類ObserverWrapper中,它是Observer的包裝類,activeStateChanged方法會根據Active狀態和處於Active狀態的組件的數量,來對onActive方法和onInactive方法回調,這兩個方法用於拓展LiveData對象。註釋1處,若是是Active狀態,會調用dispatchingValue方法,並將自身傳進去。
private void dispatchingValue(@Nullable ObserverWrapper initiator) {
//正在處於分發狀態中
if (mDispatchingValue) {
//分發無效
mDispatchInvalidated = true;//1
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;
}
複製代碼
mDispatchingValue用於標記當前是否處於分發狀態中,若是處於該狀態,則在註釋1處標記當前分發無效,直接return。一路調用過來,ObserverWrapper是不爲null的,ObserverWrapper爲null的狀況第3小節會講到,不管是那種狀況,都會調用considerNotify方法,代碼以下所示。
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {//1
return;
}
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);//2
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//noinspection unchecked
observer.mObserver.onChanged((T) mData);//3
}
複製代碼
considerNotify方法中作了屢次的判斷,註釋1處,若是ObserverWrapper的mActive值不爲true,就直接return。註釋2處,若是當前observer對應組件的狀態不是Active,就會再次調用activeStateChanged方法,並傳入false,其方法內部會再次判斷是否執行onActive方法和onInactive方法回調。若是判斷條件都知足會調用Observer的onChanged方法,這個方法正是使用LiveData的observe方法的回調。
當調用MutableLiveData的observe方法後,還須要經過postValue/setValue方法來更新數據。 frameworks/support/lifecycle/livedata-core/src/main/java/androidx/lifecycle/LiveData.java
...
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue);//1
}
};
...
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);//2
}
@MainThread //3
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
複製代碼
postValue/setValue方法都定義在LiveData中,根據註釋1和註釋2處,能夠發現postValue方法實際上就是將setValue方法切換到主線程調用。註釋3處說明setValue方法是運行在主線程中的,其內部調用了dispatchingValue方法,這個方法在第2小節介紹過,也就是dispatchingValue方法的參數ObserverWrapper爲null的狀況。 從這裏咱們能夠知道,不管是LiveData的observe方法仍是LiveData的postValue/setValue方法都會調用dispatchingValue方法。
除了以上講的經常使用的方法以外,還可能會使用到Transformations.map和Transformations.switchMap方法,這裏以Transformations.map爲例。這個方法用來在LiveData對象分發給觀察者以前對其中存儲的值進行更改, 代碼以下所示。 frameworks/support/lifecycle/livedata/src/main/java/androidx/lifecycle/Transformations.java
@MainThread
public static <X, Y> LiveData<Y> map( @NonNull LiveData<X> source, @NonNull final Function<X, Y> mapFunction) {
final MediatorLiveData<Y> result = new MediatorLiveData<>();//1
result.addSource(source, new Observer<X>() {
@Override
public void onChanged(@Nullable X x) {
result.setValue(mapFunction.apply(x));
}
});
return result;
}
複製代碼
Transformations.map方法運行在主線程,註釋1處建立了MediatorLiveData,緊接着調用了它的addSource方法: support/lifecycle/livedata/src/main/java/androidx/lifecycle/MediatorLiveData.java
*/
@MainThread
public <S> void addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged) {
Source<S> e = new Source<>(source, onChanged);//1
Source<?> existing = mSources.putIfAbsent(source, e);
if (existing != null && existing.mObserver != onChanged) {
throw new IllegalArgumentException(
"This source was already added with the different observer");
}
if (existing != null) {
return;
}
if (hasActiveObservers()) {
e.plug();//2
}
}
複製代碼
註釋1處將傳進來的LiveData和onChanged封裝到Source類中,註釋2處調用了Source的plug方法:
private static class Source<V> implements Observer<V> {
final LiveData<V> mLiveData;
final Observer<? super V> mObserver;
int mVersion = START_VERSION;
Source(LiveData<V> liveData, final Observer<? super V> observer) {
mLiveData = liveData;
mObserver = observer;
}
void plug() {
mLiveData.observeForever(this);//1
}
void unplug() {
mLiveData.removeObserver(this);
}
@Override
public void onChanged(@Nullable V v) {
if (mVersion != mLiveData.getVersion()) {
mVersion = mLiveData.getVersion();
mObserver.onChanged(v);//2
}
}
}
複製代碼
註釋2處能夠看到,Transformations.map方法傳入的Observer的回調在這裏進行處理。註釋1處,Source的plug方法會調用LiveData的observeForever方法,這個和第2小節所講的內容有什麼區別呢?咱們再往下看。 frameworks/support/lifecycle/livedata-core/src/main/java/androidx/lifecycle/LiveData.java
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
assertMainThread("observeForever");
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);//1
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && existing instanceof LiveData.LifecycleBoundObserver) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
wrapper.activeStateChanged(true);
}
複製代碼
註釋1處用AlwaysActiveObserver來對Observer進行包裝,緊接着調用AlwaysActiveObserver的activeStateChanged方法,其內部實際調用的是ObserverWrapper的activeStateChanged方法,這個在第二小節已經作了分析,就再也不贅述了。來看AlwaysActiveObserver類是如何定義的。 frameworks/support/lifecycle/livedata-core/src/main/java/androidx/lifecycle/LiveData.java
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer<? super T> observer) {
super(observer);
}
@Override
boolean shouldBeActive() {
return true;
}
}
複製代碼
AlwaysActiveObserver是LiveData的內部類,它繼承自ObserverWrapper,AlwaysActiveObserver是LiveData的內部類和ObserverWrapper的區別就是,它是永遠處於Active狀態的。
接下來給出LiveData關聯類的UML圖,看明白這個圖之後,再回去從新閱讀本文,也許你會收穫更多。
能夠看到,在講解LiveData時涉及的大部分類都在這個圖中,其中MutableLiveData繼承自LiveData,LifecycleOwner和Observer和LiveData有關聯的關係,ObserverWrapper是Observer的包裝類,所以它們有着關聯的關係,其餘的類你們看圖就知道了。更多的內容請關注個人獨立博客的知識體系:
liuwangshu.cn/system/
這裏不只分享大前端、Android、Java等技術,還有程序員成長類文章。