目錄介紹
- 01.LiveData是什么東西
- 02.使用LiveData的優(yōu)勢
- 03.使用LiveData的步驟
- 04.簡單使用LiveData
- 05.observe()和observerForever()
- 06.LiveData原理介紹
- 07.observe訂閱源碼分析
- 08.setValue發(fā)送源碼分析
- 09.observeForever源碼
- 10.LiveData源碼總結(jié)
00.使用LiveData實現(xiàn)bus事件總線
- 利用LiveData實現(xiàn)事件總線,替代EventBus。充分利用了生命周期感知功能,可以在activities, fragments, 或者 services生命周期是活躍狀態(tài)時更新這些組件。支持發(fā)送普通事件,也可以發(fā)送粘性事件;還可以發(fā)送延遲消息,以及輪訓(xùn)延遲消息等等。
- https://github.com/yangchong211/YCLiveDataBus
01.LiveData是什么東西
- 基于觀察者模式
- LiveData是一種持有可被觀察數(shù)據(jù)的類。LiveData需要一個觀察者對象,一般是Observer類的具體實現(xiàn)。當(dāng)觀察者的生命周期處于STARTED或RESUMED狀態(tài)時,LiveData會通知觀察者數(shù)據(jù)變化。
- 感知生命周期
- 和其他可被觀察的類不同的是,LiveData是有生命周期感知能力的,這意味著它可以在activities, fragments, 或者 services生命周期是活躍狀態(tài)時更新這些組件。那么什么是活躍狀態(tài)呢?就是STARTED和RESUMED就是活躍狀態(tài),只有在這兩個狀態(tài)下LiveData是會通知數(shù)據(jù)變化的。
- 自動解除數(shù)據(jù)訂閱
- 要想使用LiveData(或者這種有可被觀察數(shù)據(jù)能力的類)就必須配合實現(xiàn)了LifecycleOwner的對象使用。在這種情況下,當(dāng)對應(yīng)的生命周期對象DESTORY時,才能移除觀察者。這對Activity或者Fragment來說顯得尤為重要,因為他們可以在生命周期結(jié)束的時候立刻解除對數(shù)據(jù)的訂閱,從而避免內(nèi)存泄漏等問題。
02.使用LiveData的優(yōu)勢
2.1 具有很明顯的優(yōu)點
- UI和實時數(shù)據(jù)保持一致
- 因為LiveData采用的是觀察者模式,這樣一來就可以在數(shù)據(jù)發(fā)生改變時獲得通知,更新UI。
- 不會發(fā)生內(nèi)存泄露
- 觀察者被綁定到組件的生命周期上,當(dāng)被綁定的組件銷毀(onDestroy)時,觀察者會立刻自動清理自身的數(shù)據(jù)。
- 不會再產(chǎn)生由于Activity處于stop狀態(tài)而引起的崩潰
- 例如:當(dāng)Activity處于后臺狀態(tài)時,是不會收到LiveData的任何事件的。
- 不需要再解決生命周期帶來的問題
- LiveData可以感知被綁定的組件的生命周期,只有在活躍狀態(tài)才會通知數(shù)據(jù)變化。
- 實時數(shù)據(jù)刷新
- 當(dāng)組件處于活躍狀態(tài)或者從不活躍狀態(tài)到活躍狀態(tài)時總是能收到最新的數(shù)據(jù)
- 解決Configuration Change問題
- 在屏幕發(fā)生旋轉(zhuǎn)或者被回收再次啟動,立刻就能收到最新的數(shù)據(jù)。
- 數(shù)據(jù)共享
- 如果對應(yīng)的LiveData是單例的話,就能在app的組件間分享數(shù)據(jù)。這部分詳細的信息可以參考繼承LiveData
2.2 細節(jié)點補充
- 組件和數(shù)據(jù)相關(guān)的內(nèi)容能實時更新,組件在前臺的時候能夠?qū)崟r收到數(shù)據(jù)改變的通知,當(dāng)組件從后臺到前臺來時,LiveData能夠?qū)⒆钚碌臄?shù)據(jù)通知組件,因此保證了組件中和數(shù)據(jù)相關(guān)的內(nèi)容能夠?qū)崟r更新。
- 如果橫豎屏切換(configuration change)時,不需要額外的處理來保存數(shù)據(jù),當(dāng)屏幕方向變化時,組件會被recreate,然而系統(tǒng)并不能保證你的數(shù)據(jù)能夠被恢復(fù)的。當(dāng)我們采用LiveData保存數(shù)據(jù)時,因為數(shù)據(jù)和組件分離了。當(dāng)組件被recreate,數(shù)據(jù)還是存在LiveData中,并不會被銷毀。
03.使用LiveData的步驟
- 創(chuàng)建一個持有某種數(shù)據(jù)類型的LiveData (通常是在ViewModel中)
- 創(chuàng)建一個定義了onChange()方法的觀察者。這個方法是控制LiveData中數(shù)據(jù)發(fā)生變化時,采取什么措施 (比如更新界面)。通常是在UI Controller (Activity/Fragment) 中創(chuàng)建這個觀察者。
- 通過 observe()方法連接觀察者和LiveData。observe()方法需要攜帶一個LifecycleOwner類。這樣就可以讓觀察者訂閱LiveData中的數(shù)據(jù),實現(xiàn)實時更新。
04.簡單使用LiveData
4.1 單獨使用LiveData
- 舉一個最簡單的案例代碼:
liveData = new MutableLiveData<>(); liveData.observe(this, new Observer<String>() { @Override public void onChanged(@Nullable final String newText) { // 更新數(shù)據(jù) tv3.setText(newText); } }); liveData.setValue("小楊真的是一個逗比么"); - 那么上面這一段代碼大概是什么意思呢?
- 首先創(chuàng)建一個 MutableLiveData(LiveData是抽象類)對象 ,通過 observe 方法可以訂閱修改數(shù)據(jù)的通知,通過 postValue()或者 setValue() 方法發(fā)送事件更新數(shù)據(jù),已經(jīng)訂閱的 Observer 能夠得到數(shù)據(jù)更改的通知,就會回調(diào) onChanged() 方法。
4.2 使用LiveData配合ViewModel
- LiveData是一個數(shù)據(jù)的包裝。具體的包裝對象可以是任何數(shù)據(jù),包括集合。它是一個抽象類,首先先創(chuàng)建一個類實現(xiàn)LiveData。代碼如下所示:
public class TextViewModel extends ViewModel { /** * LiveData是抽象類,MutableLiveData是具體實現(xiàn)類 */ private MutableLiveData<String> mCurrentText; public MutableLiveData<String> getCurrentText() { if (mCurrentText == null) { mCurrentText = new MutableLiveData<>(); } return mCurrentText; } } - 創(chuàng)建一個觀察的對象,觀察LiveData中的數(shù)據(jù)。目前在組件的onCreate()方法中開始觀察數(shù)據(jù),代碼如下所示:
- 思考下,可以在onResume()中調(diào)用么,個人覺得不太好。因為系統(tǒng)會多次調(diào)用onResume()方法。
private void initLiveData() { // 創(chuàng)建一個持有某種數(shù)據(jù)類型的LiveData (通常是在ViewModel中) model = ViewModelProviders.of(this).get(TextViewModel.class); // 創(chuàng)建一個定義了onChange()方法的觀察者 // 開始訂閱 final Observer<String> nameObserver = new Observer<String>() { @Override public void onChanged(@Nullable final String newText) { // 更新數(shù)據(jù) tvText.setText(newText); } }; // 通過 observe()方法連接觀察者和LiveData,注意:observe()方法需要攜帶一個LifecycleOwner類 model.getCurrentText().observe(this, nameObserver); } - 然后去創(chuàng)建更新對象數(shù)據(jù)內(nèi)容的對象。如何去更新那個文本中的數(shù)據(jù)呢?代碼如下所示:
- 想要在UI Controller中改變LiveData中的值呢?(比如點擊某個Button設(shè)置文本內(nèi)容的更改)。
- LiveData并沒有提供這樣的功能,但是Architecture Component提供了MutableLiveData這樣一個類,可以通過setValue(T)和postValue(T)方法來修改存儲在LiveData中的數(shù)據(jù)。MutableLiveData是LiveData的一個子類,從名稱上也能看出這個類的作用。
- 調(diào)用setValue()方法就可以把LiveData中的值改為 "小楊真的是一個逗比么" 。同樣,通過這種方法修改LiveData中的值同樣會觸發(fā)所有對這個數(shù)據(jù)感興趣的類。那么setValue()和postValue()有什么不同呢?區(qū)別就是setValue()只能在主線程中調(diào)用,而postValue()可以在子線程中調(diào)用。
findViewById(R.id.tv_click).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { count++; String text; switch (count%5){ case 1: text = "小楊真的是一個逗比么"; break; case 2: text = "逗比趕緊來star吧"; break; case 3: text = "小楊想成為大神"; break; case 4: text = "開始刷新數(shù)據(jù)啦"; break; default: text = "變化成默認的數(shù)據(jù)"; break; } model.getCurrentText().setValue(text); } });
05.observe()和observerForever()
- 一般我們使用 LiveData 的 observe(),當(dāng)數(shù)據(jù)更新后,LiveData 會通知它的所有活躍的觀察者。
- 與 RxJava 不同的,LiveData 只會通知活躍的觀察者,例如 Activity 位于 Destroyed 狀態(tài)時是不活躍的,因此不會收到通知。
- 當(dāng)然我們也可以使用 LiveData 的 observerForever() 方法進行訂閱,區(qū)別是 observerForever() 不會受到 Activity 等組件的生命周期的影響,只要數(shù)據(jù)更新就會收到通知。
06.LiveData原理介紹
6.1 簡單的原理介紹
- LiveData可對數(shù)據(jù)進行觀測, 并具有生命周期感知能力, 這就意味著當(dāng)liveData只會在生命周期處于活躍(inActive)的狀態(tài)下才會去執(zhí)行觀測動作, 而他的能力賦予不能脫離LifeCycle的范圍。
- 需要注意的是,LiveData內(nèi)維護的mVersion表示的是發(fā)送信息的版本,每次發(fā)送一次信息, 它都會+1, 而ObserverWrapper內(nèi)維護的mLastVersion為訂閱觸發(fā)的版本號, 當(dāng)訂閱動作生效的時候, 它的版本號會和發(fā)送信息的版本號同步.他們初始值都為-1。
6.2 然后思考一些問題
- a.liveData如何實現(xiàn)訂閱者模式,如何處理發(fā)送事件?
- b.如何做到感知生命周期的,怎么跟 LifecycleOwner 進行綁定的?
- c.LiveData 只在 LifecycleOwner active 狀態(tài)發(fā)送通知,是怎么處理的?
- d.LiveData 會自動在 DESTROY 的狀態(tài)下取消訂閱,是怎么處理的?
- e.生命周期變化后數(shù)據(jù)處理流程是怎么樣的?
- f.為什么觀察者只能與一個LifecycleOwner綁定,而不是多個?
07.observe訂閱源碼分析
7.1 首先看看observe方法源碼
- 直接查看源代碼,如下所示:
- 當(dāng)前綁定的組件(activity或者fragment)狀態(tài)為DESTROYED的時候, 則會忽視當(dāng)前的訂閱請求,也就是忽略owner的注冊;
- 如果需要與生命周期綁定, 則需要傳入LifecycleOwner對象, 將我們的LiveData數(shù)據(jù)觀測者(Observer)包裝注冊到生命周期的觀測者中, 就是源碼中創(chuàng)建wrapper對象過程;
- 需要注意的問題是,不能添加具有不同生命周期的相同觀察者,否則就會拋出IllegalArgumentException異常,但是owner可以add多個Observer;
- 最后添加一個LifecycleObserver,它將在LifecycleOwner更改狀態(tài)時得到通知,并做出及時的對應(yīng)更新活動。
@MainThread public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) { //當(dāng)前綁定的組件(activity或者fragment)狀態(tài)為DESTROYED的時候, 則會忽視當(dāng)前的訂閱請求 if (owner.getLifecycle().getCurrentState() == DESTROYED) { // ignore return; } //創(chuàng)建生命周期感知的觀察者包裝類 LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer); //如果指定的鍵尚未與某個值關(guān)聯(lián),則將其與給定的值關(guān)聯(lián) ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper); //對應(yīng)觀察者只能與一個owner綁定 if (existing != null && !existing.isAttachedTo(owner)) { throw new IllegalArgumentException("Cannot add the same observer" + " with different lifecycles"); } if (existing != null) { return; } //lifecycle注冊 //添加一個LifecycleObserver,它將在LifecycleOwner更改狀態(tài)時得到通知 owner.getLifecycle().addObserver(wrapper); }
7.2 看看LifecycleBoundObserver源碼
- 然后看一下觀察者類LifecycleBoundObserver的源代碼
- LifecycleBoundObserver對象, 它繼承于ObserverWrapper, 并最終實現(xiàn)了GenericLifecycleObserver接口;
- 在發(fā)生狀態(tài)轉(zhuǎn)換事件時,會調(diào)用onStateChanged方法,在這個方法中,如果是DESTROYED狀態(tài),則先要移除觀察者,然后在取到生命周期狀態(tài)變更事件
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver { @NonNull final LifecycleOwner mOwner; LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<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) { // 當(dāng)接收到 DESTROYED 的事件會自動解除跟 owner 的綁定 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<T> mObserver; boolean mActive; int mLastVersion = START_VERSION; ObserverWrapper(Observer<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; if (wasInactive && mActive) { onActive(); } if (LiveData.this.mActiveCount == 0 && !mActive) { onInactive(); } if (mActive) { dispatchingValue(this); } } } //接口 public interface GenericLifecycleObserver extends LifecycleObserver { /** * Called when a state transition event happens. * * @param source The source of the event * @param event The event */ void onStateChanged(LifecycleOwner source, Lifecycle.Event event); } - 通過上面的代碼可以發(fā)現(xiàn)什么?
- GenericLifecycleObserver是一個接口,ObserverWrapper是一個抽象類,而LifecycleBoundObserver則是ObserverWrapper的子類,并且重寫了其中幾個方法;
- 在LifecycleBoundObserver的shouldBeActive()方法,在 owner 處于至少是 STARTED 的狀態(tài)下認為是 active 狀態(tài);
- 而且它也實現(xiàn)了 GenericLifecycleObserver 接口,可以監(jiān)聽 lifecycle 回調(diào)。在 onStateChanged() 方法里處理了生命周期改變的事件,在這個方法中,當(dāng)接收到 DESTROYED 的事件會自動解除跟 owner 的綁定;
- 將下個流程交給了 activeStateChanged(),這里具體可以看抽象類ObserverWrapper中的activeStateChanged源碼;
- 看一下ObserverWrapper抽象類中activeStateChanged方法中,onActive和onInactive分別干什么呢?
- 對于onActive方法,當(dāng)活動觀察者的數(shù)量從0變?yōu)?時調(diào)用;對于onInactive方法,當(dāng)活動觀察者的數(shù)量從1變?yōu)?時調(diào)用
if (wasInactive && mActive) { onActive(); } if (LiveData.this.mActiveCount == 0 && !mActive) { onInactive(); } - 看一下ObserverWrapper抽象類中activeStateChanged方法中,dispatchingValue是干什么呢?
- 這個方法在分析下面setValue源碼時還會說到,具體看下面的介紹!
7.3 看看mObservers.putIfAbsent操作
- 關(guān)于observe源碼中這一行代碼ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper)作用是什么呢?
- mObservers.putIfAbsent(observer, wrapper)存入容器中,mObservers.putIfAbsent這個添加數(shù)據(jù)的方式比較少見。
- 看了下面源代碼可知,支持鍵值對存儲,用鏈表實現(xiàn),不是線程安全的。既然這里有存數(shù)據(jù),那肯定有地方會取數(shù)據(jù)用到,這個后面會說到……
//mObservers是一個集合 private SafeIterableMap<Observer<T>, ObserverWrapper> mObservers = new SafeIterableMap<>(); //在SafeIterableMap類中的putIfAbsent方法 public V putIfAbsent(@NonNull K key, @NonNull V v) { Entry<K, V> entry = get(key); if (entry != null) { return entry.mValue; } put(key, v); return null; } protected Entry<K, V> put(@NonNull K key, @NonNull V v) { Entry<K, V> newEntry = new Entry<>(key, v); mSize++; if (mEnd == null) { mStart = newEntry; mEnd = mStart; return newEntry; } mEnd.mNext = newEntry; newEntry.mPrevious = mEnd; mEnd = newEntry; return newEntry; }
7.4 注冊觀察者流程
- 那么注冊觀察者之后的觸發(fā)流程是怎樣的?
- 調(diào)用 observe() 注冊后,由于綁定了 owner,所以在 active 的情況下,使用LiveData中setValue發(fā)送數(shù)據(jù),則 Observer 會立馬接受到該數(shù)據(jù)修改的通知。
- observe ——> onStateChanged ——> activeStateChanged ——> dispatchingValue ——> considerNotify ——> onChanged
- 至于最終走到了onChanged方法,這個方法則是交給外部開發(fā)者處理接收消息事件的邏輯
08.setValue發(fā)送源碼分析
8.1 setValue源碼分析
- LiveData 更新數(shù)據(jù)方式有兩個,一個是 setValue() 另一個是 postValue(),這兩個方法的區(qū)別是,postValue() 在內(nèi)部會拋到主線程去執(zhí)行更新數(shù)據(jù),因此適合在子線程中使用;而 setValue() 則是直接更新數(shù)據(jù)。
@MainThread protected void setValue(T value) { assertMainThread("setValue"); // 這里的 mVersion,它本問題關(guān)鍵,每次更新數(shù)據(jù)都會自增,默認值是 -1。 mVersion++; mData = value; dispatchingValue(null); } - 跟進下 dispatchingValue() 方法,注意,這里需要重點看considerNotify代碼:
private void dispatchingValue(@Nullable ObserverWrapper initiator) { // mDispatchingValue的判斷主要是為了解決并發(fā)調(diào)用dispatchingValue的情況 // 當(dāng)對應(yīng)數(shù)據(jù)的觀察者在執(zhí)行的過程中, 如有新的數(shù)據(jù)變更, 則不會再次通知到觀察者。所以觀察者內(nèi)的執(zhí)行不應(yīng)進行耗時工作 if (mDispatchingValue) { //給分發(fā)失敗打個標記 mDispatchInvalidated = true; return; } // 標記分發(fā)開始 mDispatchingValue = true; do { mDispatchInvalidated = false; //這里需要注意:區(qū)分ObserverWrapper對象為空,和不為空的邏輯是不一樣的 if (initiator != null) { // 等下重點看這里的代碼 considerNotify(initiator); initiator = null; } else { //可以發(fā)現(xiàn)這里用到mObservers集合,使用迭代器遍歷數(shù)據(jù) for (Iterator<Map.Entry<Observer<T>, ObserverWrapper>> iterator = mObservers.iteratorWithAdditions(); iterator.hasNext(); ) { // 等下重點看這里的代碼 considerNotify(iterator.next().getValue()); if (mDispatchInvalidated) { break; } } } } while (mDispatchInvalidated); // 標記分發(fā)開始 mDispatchingValue = false; } - 接下來看一下上面源碼中initiator對象為空判斷邏輯區(qū)別
- dispatchingValue 這里分兩種情況:ObserverWrapper不為null和ObserverWrapper為null
- ObserverWrapper不為null 的情況。LifecycleBoundObserver.onStateChanged 方法里調(diào)用了 activeStateChanged ,而該方法調(diào)用dispatchingValue(this);傳入了 this ,也就是 LifecycleBoundObserver ,這時候不為 null 。也就是說生命周期改變觸發(fā)的流程就是這種情況,這種情況下,只會通知跟該 Owner 綁定的 Observer。
- ObserverWrapper為null 的情況。經(jīng)過分析發(fā)現(xiàn)在setValue方法中調(diào)用dispatchingValue(null)傳遞了空對象,這個時候的流程則會通知 active 的mObservers
8.2 看一下considerNotify()做什么
- 然后看一下considerNotify() 方法做了什么,代碼如下所示,這里有道詞典翻譯下注釋
- 如果ObserverWrapper的mLastVersion小于LiveData的mVersion,就會去回調(diào)mObserver的onChanged方法。
- 每個新的訂閱者,其version都是-1,LiveData一旦設(shè)置過其version是大于-1的(每次LiveData設(shè)置值都會使其version加1),這樣就會導(dǎo)致LiveDataBus每注冊一個新的訂閱者,這個訂閱者立刻會收到一個回調(diào),即使這個設(shè)置的動作發(fā)生在訂閱之前。
private void considerNotify(ObserverWrapper observer) { if (!observer.mActive) { return; } // 檢查最新的狀態(tài)b4調(diào)度。也許它改變了狀態(tài),但我們還沒有得到事件。 // 我們還是先檢查觀察者。活動,以保持它作為活動的入口。 // 因此,即使觀察者移動到一個活動狀態(tài),如果我們沒有收到那個事件,我們最好不要通知一個更可預(yù)測的通知順序。 if (!observer.shouldBeActive()) { observer.activeStateChanged(false); return; } //注意認真看下面的代碼 if (observer.mLastVersion >= mVersion) { return; } observer.mLastVersion = mVersion; //noinspection unchecked observer.mObserver.onChanged((T) mData); } - 思考一下dispatchingValue除了setValue會調(diào)用,其他還有地方調(diào)用么?
- dispatchingValue除了在我們主動更新數(shù)據(jù)的時候會觸發(fā),
- 當(dāng)LifeCircleOwner的狀態(tài)發(fā)生變化的時候,會調(diào)用LiveData.ObserverWrapper的activeStateChanged函數(shù)。
- 在我們的觀察者狀態(tài)變更(inactive->active)的時候, 也會通知到, 這就導(dǎo)致了LiveData必然支持粘性事件。
- 如果這個時候ObserverWrapper的狀態(tài)是active,就會調(diào)用LiveData的dispatchingValue。
- 它主要是處理分發(fā)通知邏輯,并且在分發(fā)通知前會判斷 owner 的狀態(tài),再加上 LiveData 本身內(nèi)部的版本管理,確保了只會發(fā)送最新的數(shù)據(jù)給 active 狀態(tài)下的 Observer。
- LiveData 對同時多次修改數(shù)據(jù)做了處理,如果同時多次修改,只會修改為最新的數(shù)據(jù)。
private abstract class ObserverWrapper { final Observer<T> mObserver; boolean mActive; int mLastVersion = START_VERSION; //省略部分代碼 void activeStateChanged(boolean newActive) { if (newActive == mActive) { return; } // 當(dāng)observer的狀態(tài)從active->inactive, 或者inactive->active的時候走以下流程 // 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(); } //當(dāng)observer是從inactive->active的時候,需要通知到觀察者 if (mActive) { dispatchingValue(this); } } }
8.3 發(fā)送消息事件流程
- 那么發(fā)送消息事件之后的觸發(fā)流程是怎樣的?
- setValue ——> dispatchingValue(null) ——> considerNotify(注意,這里是個for迭代器循環(huán),表示通知所有觀察者) ——> onChanged
09.observeForever源碼
- 這個方法是干什么用的呢?看一下源代碼
- 將給定的觀察者添加到觀察者列表中,意味著給定的觀察者將接收所有事件,并且永遠不會被自動刪除,不管在什么狀態(tài)下都能接收到數(shù)據(jù)的更改通知
@MainThread public void observeForever(@NonNull Observer<T> observer) { // 創(chuàng)建一個AlwaysActiveObserver對象 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; } //刷新數(shù)據(jù) wrapper.activeStateChanged(true); }
10.LiveData源碼總結(jié)
- LiveData的觀察者可以聯(lián)動生命周期, 也可以不聯(lián)動。在聯(lián)動生命周期時,會自動在 DESTROYED 的狀態(tài)下移除 Observer ,取消訂閱,所以不用擔(dān)心內(nèi)存泄露;
- LiveData的觀察者只能與一個LifecycleOwner綁定, 否則會拋出異常。而一個 owner 可以綁定多個 Observer 實例;
- LiveData 跟 LifecycleOwner 綁定,能感知生命周期變化,并且只會在 LifecycleOwner 處于 Active 狀態(tài)(STARTED/RESUMED)下通知數(shù)據(jù)改變;如果數(shù)據(jù)改變發(fā)生在非 active 狀態(tài),數(shù)據(jù)會變化,但是不發(fā)送通知,等 owner 回到 active 的狀態(tài)下,再發(fā)送通知;
- 使用observeForever()方法,會注意AlwaysActiveObserver對象,意味著給定的觀察者將接收所有事件,并且永遠不會被自動刪除,不管在什么狀態(tài)下都能接收到數(shù)據(jù)的更改通知
- LiveData 利用版本管理、綁定 Lifecycle 確保了只會發(fā)送最新的數(shù)據(jù)給 active 狀態(tài)下的 Observer
- image
- image
參考博客
- https://developer.android.com/reference/android/arch/lifecycle/LiveData
- https://juejin.im/post/5dce5b16f265da0ba5279b11
- https://mp.weixin.qq.com/s/glbd3mzU_cUPGAlJMlQ5Hg
- https://github.com/googlesamples/android-architecture-components
- https://mp.weixin.qq.com/s/yzR2LAor7dUmZDctG2g7MQ

