基於: macOs:10.14/AS:3.4/Android build-tools:28.0.0java
看源碼前先考慮下若是要本身實現 LiveData
應該怎麼作?markdown
基本作法:多線程
setter
方法用於更新目標數據;Observer
);擴展:app
setter
須要考慮同步;Observer
須要提供 Lifecycle
相關邏輯支持,包括:
Observer
能夠收到數據更新;onDestroy()
時自動移除 Observer
等;數據變化
呢? 最簡單直接的作法是每次觸發 setter
方法時都看成數據發生了變化, 遍歷通知全部 Observer
便可, 更進一步的斷定交給調用方; ......// 定義 livedata object ParaConfig { // 定義一個私有的 `MutableLiveData` private val msgLiveData = MutableLiveData<String>() // 開放給外部獲取數據更新時,提供不可變的 `LiveData` 便可; fun getMsgLiveData(): LiveData<String> = msgLiveData fun updateMsg(msg: String, inBgThread: Boolean = false) { if (inBgThread) { msgLiveData.postValue(msg) // 在子線程中更新數據 } else { msgLiveData.value = msg // 在主線程中更新數據 } } } 複製代碼
// 添加 `Observer` class LiveDataFrag : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 添加一個跟生命週期相關的 `Observer` ParaConfig.getMsgLiveData().observe(this, Observer<String> { newMsg -> tv_msg.text = newMsg }) // 無視生命週期, 每次數據變化時都會回調,須要自行移除observer ParaConfig.getMsgLiveData().observeForever { Logger.d("observeForever: $it","tag_livedata") } } } 複製代碼
看源碼我仍是習慣從調用入口一步步往下看, 如下也是按照這種順序來;ide
Observer
// LiveData.java public abstract class LiveData<T> { private static final Object NOT_SET = new Object(); // 實際數據,類型爲 Object 而非 T private volatile Object mData = NOT_SET; // 存儲全部的 Observer private SafeIterableMap<Observer<T>, ObserverWrapper> mObservers = new SafeIterableMap<>(); // 添加跟生命週期相關的 observer // 目標數據 @MainThread public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) { // 若 LifecycleOwner 已處於已被銷燬,則忽略該 observer if (owner.getLifecycle().getCurrentState() == DESTROYED) { return; } // 將 LifecycleOwner 和 Observer 功能進行綁定包裝 // 生成支持生命週期感知的 Observer: LifecycleBoundObserver LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer); // 避免重複添加相同的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; } // 實現對 LifecycleOwner 生命週期的感知 // 關鍵仍是 LifecycleBoundObserver 類,咱們立刻進去看一下 owner.getLifecycle().addObserver(wrapper); } // 無視生命週期, 每次數據發生變化時,都會回調通知 Observer // 須要手動在不須要時移除 Observer @MainThread public void observeForever(@NonNull Observer<T> observer) { 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); } } 複製代碼
MutableLiveData
只是簡單重寫了 LiveData
的 setValue(T)
/postValue(T)
方法, 改成 public
而已;post
setValue(T)
解析// LiveData.java @MainThread protected void setValue(T value) { // 只能在UI線程中調用,不然拋出異常,崩潰 assertMainThread("setValue"); mVersion++; mData = value; dispatchingValue(null); } private boolean mDispatchingValue; // 若參數 initiator 非空,則表示只通知特定的 ObserverWrapper, 不然是回調通知全部 ObserverWrapper // 因爲只在主線程中調用,所以不用作多線程處理 private void dispatchingValue(@Nullable ObserverWrapper initiator) { // 小技巧: 在遍歷通知各 ObserverWrapper 期間, 若數據發生了變化, 則會從新遍歷通知 if (mDispatchingValue) { mDispatchInvalidated = true; return; } mDispatchingValue = true; do { mDispatchInvalidated = false; if (initiator != null) {// initiator 非空時,只更新特定 ObserverWrapper considerNotify(initiator); // 實際更新數據的方法 initiator = null; } else { // 不然遍歷更新全部 ObserverWrapper for (Iterator<Map.Entry<Observer<T>, ObserverWrapper>> iterator = mObservers.iteratorWithAdditions(); iterator.hasNext(); ) { considerNotify(iterator.next().getValue()); // 若數據發生變化, 則退出for循環 // 而外層 do...while() 斷定條件爲true,就會從新遍歷通知各 ObserverWrapper; if (mDispatchInvalidated) { break; } } } } while (mDispatchInvalidated); mDispatchingValue = false; } // 判斷是否要將數據分發到指定的 ObserverWrapper private void considerNotify(ObserverWrapper observer) { // 是否能夠分發數據到指定的 observer, 由 mActive 來控制 // 因此 mActive 很重要,具體下一節解讀 if (!observer.mActive) { return; } // 二次確認狀態, 可能生命週期發生了變化,但 mActive 並未改變 if (!observer.shouldBeActive()) { // active -> inactive 時通知更新狀態 // inactive 狀態下就不須要分發數據了 observer.activeStateChanged(false); return; } // 若 ObserverWrapper 持有的數據值已經是最新版本, 天然也不用分發 if (observer.mLastVersion >= mVersion) { return; } observer.mLastVersion = mVersion; // 通知 observer 數據有更新 // observer.mObserver 是調用方實際傳入的 observer.mObserver.onChanged((T) mData); } 複製代碼
用於子線程調用的 postValue(T)
會發射一個 Runnable
到主線程中, 最終也是經過 setValue(T)
來實現數據分發; 固然, postValue(T)
也能夠在主線程調用,不過是畫蛇添足,如:ui
// observer會先收到 "msgFromSetValue" 而後才收到 "msgFromPostValue" someBtnView.setOnClickListener { msgLiveData.postValue("msgFromPostValue") msgLiveData.value = "msgFromSetValue" } 複製代碼
ObserverWrapper
類解析// LiveData 的內部抽象類 // 包裝用戶傳入的 Observer, 提供數據版本記錄以及active狀態(生命週期)判斷 private abstract class ObserverWrapper { final Observer<T> mObserver; boolean mActive; // 肯定當前 ObserverWrapper 是否生效,true時纔可進行數據更新 int mLastVersion = START_VERSION; // 當前持有的數據版本號,初始值爲 -1 ObserverWrapper(Observer<T> observer) { mObserver = observer; } // 判斷該 Observer 是否有效, true 時纔會觸發 activeStateChanged() abstract boolean shouldBeActive(); boolean isAttachedTo(LifecycleOwner owner) { return false; } void detachObserver() { } // 更新本 ObserverWrapper 的狀態 void activeStateChanged(boolean newActive) { // 若狀態沒變化,不須要更新,直接返回 if (newActive == mActive) { return; } mActive = newActive; boolean wasInactive = LiveData.this.mActiveCount == 0; LiveData.this.mActiveCount += mActive ? 1 : -1; // 處於 active 狀態的 observer 數量從0 -> 1時,觸發 onActive() 方法 if (wasInactive && mActive) { onActive(); } // 處於 active 狀態的 observer 數量從 1 -> 0時,觸發 onInactive() 方法 // 提供給觀察者釋放資源的機會 if (LiveData.this.mActiveCount == 0 && !mActive) { onInactive(); } // observer 從 inactive -> active 時, 更新數據 if (mActive) { // 將數據發送給該 observer dispatchingValue(this); } } } 複製代碼
此類並未給出 inactive/active 具體是何種狀態, 具體應是由 shouldBeActive()
來肯定, 所以須要從子類查找;this
子類 AlwaysActiveObserver
比較簡單, 只是將shouldBeActive()
固定返回 true
,表示一直生效, 每次數據發生變化時都須要發送通知; 咱們看下 LifecycleBoundObserver
類;spa
LifecycleBoundObserver
解析// LiveData 內部類 // 將 LifecycleObserver 和 ObserverWrapper 結合,當生命週期變化時,通知 ObserverWrapper 更新數據 class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver { @NonNull final LifecycleOwner mOwner; LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<T> observer) { super(observer); mOwner = owner; } @Override boolean shouldBeActive() { // 此處定義了哪些生命週期是 `active` 的 // 結合 Lifecycle.State 類 ,咱們知道是: STARTED/RESUMED 兩種狀態 // 對應於生命週期 `onStart()` 以後到 `onStop()` 以前 return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED); } // 生命週期變化時回調本方法 @Override public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) { // 若當前 LifecycleOwner onDestory() 了, 則自動移除 observer, 避免內存泄露 if (mOwner.getLifecycle().getCurrentState() == DESTROYED) { removeObserver(mObserver); return; } // 將 shouldBeActive() 返回的狀態當作本 ObserverWrapper 的狀態 // 即 mActive = shouldBeActive() activeStateChanged(shouldBeActive()); } @Override boolean isAttachedTo(LifecycleOwner owner) { return mOwner == owner; } @Override void detachObserver() { mOwner.getLifecycle().removeObserver(this); } } 複製代碼
Observer
的添加:
observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer)
observeForever(@NonNull Observer<T> observer)
LifecycleOwner
的 Observer
時, 若發生 onDestory()
,則會自動移除 Observer
;LifecycleOwner
處於 onStart()
/onResume()
/onPause()
生命週期時,纔會分發;Observer
數量從 1 -> 0, 回調 onInactive()
,適用於子類進行資源釋放;Observer
數量從 0 -> 1, 回調 onActive()
;LiveData
類和 ObserverWrapper
類都會在內部持有一個數據版本號;LiveData
數據發生變化時,會切換到主線程,而後遍歷全部 Observer
, 並將數據分發給處於 active 狀態而且數據版本號不一致的 Observer
;