基於: macOs:10.14/AS:3.4/Android build-tools:28.0.0java
看源碼前先考慮下若是要本身實現 LiveData
應該怎麼作?多線程
基本作法:app
setter
方法用於更新目標數據;Observer
);擴展:ide
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")
}
}
}
複製代碼
看源碼我仍是習慣從調用入口一步步往下看, 如下也是按照這種順序來;post
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
而已;ui
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)
也能夠在主線程調用,不過是畫蛇添足,如:this
// 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()
來肯定, 所以須要從子類查找;spa
子類 AlwaysActiveObserver
比較簡單, 只是將shouldBeActive()
固定返回 true
,表示一直生效, 每次數據發生變化時都須要發送通知; 咱們看下 LifecycleBoundObserver
類;線程
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
;