LiveData詳細分析

目錄介紹

  • 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

參考博客

開源LiveData事件總線:https://github.com/yangchong211/YCLiveDataBus

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容