這是我參與更文挑戰的第22天,活動詳情查看: 更文挑戰java
private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
new SafeIterableMap<>();
@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);
}
複製代碼
咱們調用observer()
時,傳遞了兩個參數,第一個是LifecycleOwner
接口實例,而咱們繼承的AppCompatActivity
的父類就已經實現了這個接口,因此咱們傳this
便可;第二個參數Observer
就是咱們觀察的回調。android
先判斷是否是主線程,不是就拋異常,而後經過 owner.getLifecycle().getCurrentState()
獲取狀態,判斷是否已經被銷燬,若是已經被銷燬,直接返回(由於已經說過只對處於活躍狀態的組件作更新);git
接着將owner和observer構形成LifecycleBoundObserver
實例,這是一個內部類,裏面有關於狀態變換的一系列操做,待會詳細分析;github
而後將observer和wrapper存入map緩存中,若是observer緩存已存在而且已經和另外一個LifecycleOwner
綁定,則拋出異常;若是緩存已經存在則直接忽略;緩存
即一個 Observer 實例,只能綁定一個 LifecycleOwner,而一個 owner 能夠綁定多個 Observer 實例;markdown
最後調用addObserver方法將LifecycleBoundObserver
實例和LifecycleOwner
綁定。而addObserver是調用了LifecycleRegistry
類的實現。app
當 owner (Activity 或者 fragment) 生命週期變化的時候,會回調 LifecycleBoundObserver 的 onStateChanged 方法,onStateChanged 方法又會回調 observer 的 onChange 方法。異步
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);
return;
}
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
複製代碼
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;
}
// 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;
// 激活狀態的 observer 個數從 0 到 1
if (wasInactive && mActive) {
onActive();// 空實現,通常讓子類去重寫
}
// 激活狀態的 observer 個數從 1 到 0
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive();// 空實現,通常讓子類去重寫
}
// 激活狀態,向觀察者發送 LiveData 的值
if (mActive) {
dispatchingValue(this);
}
}
}
複製代碼
咱們來看一下 LifecycleBoundObserver
,繼承 ObserverWrapper
,實現了 GenericLifecycleObserver
接口。而 GenericLifecycleObserver
接口又實現了 LifecycleObserver
接口。它包裝了咱們外部的 observer,有點相似於代理模式。咱們能夠回顧下Lifecycle
組件相關的內容。當組件(Fragment、Activity)生命週期變化時會經過onStateChanged()方法回調過來。ide
GenericLifecycleObserver#onStateChangedoop
Activity 回調週期變化的時候,會回調 onStateChanged ,會先判斷 mOwner.getLifecycle().getCurrentState() 是否已經 destroy 了,若是。已經 destroy,直接移除觀察者。這也就是爲何咱們不須要手動 remove observer 的緣由。
若是不是銷燬狀態,會調用 activeStateChanged 方法 ,攜帶的參數爲 shouldBeActive() 返回的值。 而當 lifecycle 的 state 爲 STARTED 或者 RESUMED 的時候,shouldBeActive 方法的返回值爲 true,即表示激活。
activeStateChanged 方法中,,當 newActive 爲 true,而且不等於上一次的值,會增長 LiveData 的 mActiveCount 計數。接着能夠看到,onActive 會在 mActiveCount 爲 1 時觸發,onInactive 方法則只會在 mActiveCount 爲 0 時觸發。即回調 onActive 方法的時候活躍的 observer 剛好爲 1,回調 onInactive 方法的時候,沒有一個 Observer 處於激活狀態。
當 mActive 爲 true 時,會促發 dispatchingValue 方法。
@SuppressWarnings("WeakerAccess") /* synthetic access */
void dispatchingValue(@Nullable ObserverWrapper initiator) {
// 若是正在處理,直接返回
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
// initiator 不爲 null,調用 considerNotify 方法
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else { // 爲 null 的時候,遍歷全部的 obsever,進行分發
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
// 分發完成,設置爲 false
mDispatchingValue = false;
}
複製代碼
其中 mDispatchingValue, mDispatchInvalidated 只在 dispatchingValue 方法中使用,顯然這兩個變量是爲了防止重複分發相同的內容。當 initiator 不爲 null,只處理當前 observer,爲 null 的時候,遍歷全部的 obsever,進行分發
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);
}
複製代碼
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
複製代碼
setValue 方法中,首先,斷言是主線程,接着 mVersion + 1; 並將 value 賦值給 mData,接着調用 dispatchingValue 方法。dispatchingValue 傳遞 null,表明處理全部 的 observer。
這個時候若是咱們依附的 activity 處於 onPause 或者 onStop 的時候,雖然在 dispatchingValue 方法中直接返回,不會調用 observer 的 onChange 方法。可是當所依附的 activity 從新回到前臺的時候,會促發 LifecycleBoundObserver onStateChange 方法,onStateChange 又會調用 dispatchingValue 方法,在該方法中,由於 mLastVersion < mVersion。因此會回調 obsever 的 onChange 方法,這也就是 LiveData 設計得比較巧妙的一個地方
同理,當 activity 處於後臺的時候,您屢次調用 livedata 的 setValue 方法,最終只會回調 livedata observer 的 onChange 方法一次。
protected void postValue(T value) {
boolean postTask;
// 鎖住
synchronized (mDataLock) {
// 當前沒有人在處理 post 任務
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
// 處理完畢以後將 mPendingData 置爲 NOT_SET
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue);
}
};
複製代碼
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
assertMainThread("observeForever");
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
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);
}
複製代碼
由於 AlwaysActiveObserver 沒有實現 GenericLifecycleObserver 方法接口,因此在 Activity o生命週期變化的時候,不會回調 onStateChange 方法。從而也不會主動 remove 掉 observer。由於咱們的 obsever 被 remove 掉是依賴於 Activity 生命週期變化的時候,回調 GenericLifecycleObserver 的 onStateChange 方法。
借用網上的一張圖
LiveData主要涉及到的時序有三個:
1. 確保UI符合數據狀態 LiveData遵循觀察者模式。 當生命週期狀態改變時,LiveData會向Observer發出通知。 您能夠把更新UI的代碼合併在這些Observer對象中。沒必要去考慮致使數據變化的各個時機,每次數據有變化,Observer都會去更新UI。
2. 沒有內存泄漏 Observer會綁定具備生命週期的對象,並在這個綁定的對象被銷燬後自行清理。
3. 不會因中止Activity而發生崩潰 若是Observer的生命週期處於非活躍狀態,例如在後退堆棧中的Activity,就不會收到任何LiveData事件的通知。
4.不須要手動處理生命週期 UI組件只須要去觀察相關數據,不須要手動去中止或恢復觀察。LiveData會進行自動管理這些事情,由於在觀察時,它會感知到相應組件的生命週期變化。
5. 始終保持最新的數據 若是一個對象的生命週期變到非活躍狀態,它將在再次變爲活躍狀態時接收最新的數據。 例如,後臺Activity在返回到前臺後當即收到最新數據。
6. 正確應對配置更改 若是一個Activity或Fragment因爲配置更改(如設備旋轉)而從新建立,它會當即收到最新的可用數據。
7.共享資源 您可使用單例模式擴展LiveData對象幷包裝成系統服務,以便在應用程序中進行共享。LiveData對象一旦鏈接到系統服務,任何須要該資源的Observer都只需觀察這個LiveData對象。
LiveData
基於觀察者模式實現,而且和LifecycleOwner
進行綁定,而LifecycleOwner
又被Fragment
和Activity實現,因此它能夠感知生命週期;在當前的LifecycleOwner不處於活動狀態(例如onPasue()
、onStop()
)時,LiveData是不會回調observe()
的,由於沒有意義.LiveData
只會在LifecycleOwner
處於Active
的狀態下通知數據改變,果數據改變發生在非 active 狀態,數據會變化,可是不發送通知,等 owner
回到 active 的狀態下,再發送通知;LiveData
在DESTROYED時會移除Observer
,取消訂閱,不會出現內存泄漏postValue
在異步線程,setValue
在主線程LiveData
沒有被observe()
,那麼此時你調用這個LiveData的postValue(...)/value=...,是沒有任何做用