LiveData詳細(xì)分析

目錄介紹

  • 01.LiveData是什么東西
  • 02.使用LiveData的優(yōu)勢(shì)
  • 03.使用LiveData的步驟
  • 04.簡(jiǎn)單使用LiveData
  • 05.observe()和observerForever()
  • 06.LiveData原理介紹
  • 07.observe訂閱源碼分析
  • 08.setValue發(fā)送源碼分析
  • 09.observeForever源碼
  • 10.LiveData源碼總結(jié)

00.使用LiveData實(shí)現(xiàn)bus事件總線(xiàn)

  • 利用LiveData實(shí)現(xiàn)事件總線(xiàn),替代EventBus。充分利用了生命周期感知功能,可以在activities, fragments, 或者 services生命周期是活躍狀態(tài)時(shí)更新這些組件。支持發(fā)送普通事件,也可以發(fā)送粘性事件;還可以發(fā)送延遲消息,以及輪訓(xùn)延遲消息等等。
  • https://github.com/yangchong211/YCLiveDataBus

01.LiveData是什么東西

  • 基于觀察者模式
    • LiveData是一種持有可被觀察數(shù)據(jù)的類(lèi)。LiveData需要一個(gè)觀察者對(duì)象,一般是Observer類(lèi)的具體實(shí)現(xiàn)。當(dāng)觀察者的生命周期處于STARTED或RESUMED狀態(tài)時(shí),LiveData會(huì)通知觀察者數(shù)據(jù)變化。
  • 感知生命周期
    • 和其他可被觀察的類(lèi)不同的是,LiveData是有生命周期感知能力的,這意味著它可以在activities, fragments, 或者 services生命周期是活躍狀態(tài)時(shí)更新這些組件。那么什么是活躍狀態(tài)呢?就是STARTED和RESUMED就是活躍狀態(tài),只有在這兩個(gè)狀態(tài)下LiveData是會(huì)通知數(shù)據(jù)變化的。
  • 自動(dòng)解除數(shù)據(jù)訂閱
    • 要想使用LiveData(或者這種有可被觀察數(shù)據(jù)能力的類(lèi))就必須配合實(shí)現(xiàn)了LifecycleOwner的對(duì)象使用。在這種情況下,當(dāng)對(duì)應(yīng)的生命周期對(duì)象DESTORY時(shí),才能移除觀察者。這對(duì)Activity或者Fragment來(lái)說(shuō)顯得尤為重要,因?yàn)樗麄兛梢栽谏芷诮Y(jié)束的時(shí)候立刻解除對(duì)數(shù)據(jù)的訂閱,從而避免內(nèi)存泄漏等問(wèn)題。

02.使用LiveData的優(yōu)勢(shì)

2.1 具有很明顯的優(yōu)點(diǎn)

  • UI和實(shí)時(shí)數(shù)據(jù)保持一致
    • 因?yàn)長(zhǎng)iveData采用的是觀察者模式,這樣一來(lái)就可以在數(shù)據(jù)發(fā)生改變時(shí)獲得通知,更新UI。
  • 不會(huì)發(fā)生內(nèi)存泄露
    • 觀察者被綁定到組件的生命周期上,當(dāng)被綁定的組件銷(xiāo)毀(onDestroy)時(shí),觀察者會(huì)立刻自動(dòng)清理自身的數(shù)據(jù)。
  • 不會(huì)再產(chǎn)生由于Activity處于stop狀態(tài)而引起的崩潰
    • 例如:當(dāng)Activity處于后臺(tái)狀態(tài)時(shí),是不會(huì)收到LiveData的任何事件的。
  • 不需要再解決生命周期帶來(lái)的問(wèn)題
    • LiveData可以感知被綁定的組件的生命周期,只有在活躍狀態(tài)才會(huì)通知數(shù)據(jù)變化。
  • 實(shí)時(shí)數(shù)據(jù)刷新
    • 當(dāng)組件處于活躍狀態(tài)或者從不活躍狀態(tài)到活躍狀態(tài)時(shí)總是能收到最新的數(shù)據(jù)
  • 解決Configuration Change問(wèn)題
    • 在屏幕發(fā)生旋轉(zhuǎn)或者被回收再次啟動(dòng),立刻就能收到最新的數(shù)據(jù)。
  • 數(shù)據(jù)共享
    • 如果對(duì)應(yīng)的LiveData是單例的話(huà),就能在app的組件間分享數(shù)據(jù)。這部分詳細(xì)的信息可以參考繼承LiveData

2.2 細(xì)節(jié)點(diǎn)補(bǔ)充

  • 組件和數(shù)據(jù)相關(guān)的內(nèi)容能實(shí)時(shí)更新,組件在前臺(tái)的時(shí)候能夠?qū)崟r(shí)收到數(shù)據(jù)改變的通知,當(dāng)組件從后臺(tái)到前臺(tái)來(lái)時(shí),LiveData能夠?qū)⒆钚碌臄?shù)據(jù)通知組件,因此保證了組件中和數(shù)據(jù)相關(guān)的內(nèi)容能夠?qū)崟r(shí)更新。
  • 如果橫豎屏切換(configuration change)時(shí),不需要額外的處理來(lái)保存數(shù)據(jù),當(dāng)屏幕方向變化時(shí),組件會(huì)被recreate,然而系統(tǒng)并不能保證你的數(shù)據(jù)能夠被恢復(fù)的。當(dāng)我們采用LiveData保存數(shù)據(jù)時(shí),因?yàn)閿?shù)據(jù)和組件分離了。當(dāng)組件被recreate,數(shù)據(jù)還是存在LiveData中,并不會(huì)被銷(xiāo)毀。

03.使用LiveData的步驟

  • 創(chuàng)建一個(gè)持有某種數(shù)據(jù)類(lèi)型的LiveData (通常是在ViewModel中)
  • 創(chuàng)建一個(gè)定義了onChange()方法的觀察者。這個(gè)方法是控制LiveData中數(shù)據(jù)發(fā)生變化時(shí),采取什么措施 (比如更新界面)。通常是在UI Controller (Activity/Fragment) 中創(chuàng)建這個(gè)觀察者。
  • 通過(guò) observe()方法連接觀察者和LiveData。observe()方法需要攜帶一個(gè)LifecycleOwner類(lèi)。這樣就可以讓觀察者訂閱LiveData中的數(shù)據(jù),實(shí)現(xiàn)實(shí)時(shí)更新。

04.簡(jiǎn)單使用LiveData

4.1 單獨(dú)使用LiveData

  • 舉一個(gè)最簡(jiǎn)單的案例代碼:
    liveData = new MutableLiveData<>();
    liveData.observe(this, new Observer<String>() {
        @Override
        public void onChanged(@Nullable final String newText) {
            // 更新數(shù)據(jù)
            tv3.setText(newText);
        }
    });
    liveData.setValue("小楊真的是一個(gè)逗比么");
    
  • 那么上面這一段代碼大概是什么意思呢?
    • 首先創(chuàng)建一個(gè) MutableLiveData(LiveData是抽象類(lèi))對(duì)象 ,通過(guò) observe 方法可以訂閱修改數(shù)據(jù)的通知,通過(guò) postValue()或者 setValue() 方法發(fā)送事件更新數(shù)據(jù),已經(jīng)訂閱的 Observer 能夠得到數(shù)據(jù)更改的通知,就會(huì)回調(diào) onChanged() 方法。

4.2 使用LiveData配合ViewModel

  • LiveData是一個(gè)數(shù)據(jù)的包裝。具體的包裝對(duì)象可以是任何數(shù)據(jù),包括集合。它是一個(gè)抽象類(lèi),首先先創(chuàng)建一個(gè)類(lèi)實(shí)現(xiàn)LiveData。代碼如下所示:
    public class TextViewModel extends ViewModel {
    
        /**
         * LiveData是抽象類(lèi),MutableLiveData是具體實(shí)現(xiàn)類(lèi)
         */
        private MutableLiveData<String> mCurrentText;
    
        public MutableLiveData<String> getCurrentText() {
            if (mCurrentText == null) {
                mCurrentText = new MutableLiveData<>();
            }
            return mCurrentText;
        }
    
    }
    
  • 創(chuàng)建一個(gè)觀察的對(duì)象,觀察LiveData中的數(shù)據(jù)。目前在組件的onCreate()方法中開(kāi)始觀察數(shù)據(jù),代碼如下所示:
    • 思考下,可以在onResume()中調(diào)用么,個(gè)人覺(jué)得不太好。因?yàn)橄到y(tǒng)會(huì)多次調(diào)用onResume()方法。
    private void initLiveData() {
        // 創(chuàng)建一個(gè)持有某種數(shù)據(jù)類(lèi)型的LiveData (通常是在ViewModel中)
        model = ViewModelProviders.of(this).get(TextViewModel.class);
        // 創(chuàng)建一個(gè)定義了onChange()方法的觀察者
        // 開(kāi)始訂閱
        final Observer<String> nameObserver = new Observer<String>() {
            @Override
            public void onChanged(@Nullable final String newText) {
                // 更新數(shù)據(jù)
                tvText.setText(newText);
            }
        };
        // 通過(guò) observe()方法連接觀察者和LiveData,注意:observe()方法需要攜帶一個(gè)LifecycleOwner類(lèi)
        model.getCurrentText().observe(this, nameObserver);
    }
    
  • 然后去創(chuàng)建更新對(duì)象數(shù)據(jù)內(nèi)容的對(duì)象。如何去更新那個(gè)文本中的數(shù)據(jù)呢?代碼如下所示:
    • 想要在UI Controller中改變LiveData中的值呢?(比如點(diǎn)擊某個(gè)Button設(shè)置文本內(nèi)容的更改)。
    • LiveData并沒(méi)有提供這樣的功能,但是Architecture Component提供了MutableLiveData這樣一個(gè)類(lèi),可以通過(guò)setValue(T)和postValue(T)方法來(lái)修改存儲(chǔ)在LiveData中的數(shù)據(jù)。MutableLiveData是LiveData的一個(gè)子類(lèi),從名稱(chēng)上也能看出這個(gè)類(lèi)的作用。
    • 調(diào)用setValue()方法就可以把LiveData中的值改為 "小楊真的是一個(gè)逗比么" 。同樣,通過(guò)這種方法修改LiveData中的值同樣會(huì)觸發(fā)所有對(duì)這個(gè)數(shù)據(jù)感興趣的類(lèi)。那么setValue()和postValue()有什么不同呢?區(qū)別就是setValue()只能在主線(xiàn)程中調(diào)用,而postValue()可以在子線(xiàn)程中調(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 = "小楊真的是一個(gè)逗比么";
                    break;
                case 2:
                    text = "逗比趕緊來(lái)star吧";
                    break;
                case 3:
                    text = "小楊想成為大神";
                    break;
                case 4:
                    text = "開(kāi)始刷新數(shù)據(jù)啦";
                    break;
                default:
                    text = "變化成默認(rèn)的數(shù)據(jù)";
                    break;
            }
            model.getCurrentText().setValue(text);
        }
    });
    

05.observe()和observerForever()

  • 一般我們使用 LiveData 的 observe(),當(dāng)數(shù)據(jù)更新后,LiveData 會(huì)通知它的所有活躍的觀察者。
    • 與 RxJava 不同的,LiveData 只會(huì)通知活躍的觀察者,例如 Activity 位于 Destroyed 狀態(tài)時(shí)是不活躍的,因此不會(huì)收到通知。
  • 當(dāng)然我們也可以使用 LiveData 的 observerForever() 方法進(jìn)行訂閱,區(qū)別是 observerForever() 不會(huì)受到 Activity 等組件的生命周期的影響,只要數(shù)據(jù)更新就會(huì)收到通知。

06.LiveData原理介紹

6.1 簡(jiǎn)單的原理介紹

  • LiveData可對(duì)數(shù)據(jù)進(jìn)行觀測(cè), 并具有生命周期感知能力, 這就意味著當(dāng)liveData只會(huì)在生命周期處于活躍(inActive)的狀態(tài)下才會(huì)去執(zhí)行觀測(cè)動(dòng)作, 而他的能力賦予不能脫離LifeCycle的范圍。
  • 需要注意的是,LiveData內(nèi)維護(hù)的mVersion表示的是發(fā)送信息的版本,每次發(fā)送一次信息, 它都會(huì)+1, 而ObserverWrapper內(nèi)維護(hù)的mLastVersion為訂閱觸發(fā)的版本號(hào), 當(dāng)訂閱動(dòng)作生效的時(shí)候, 它的版本號(hào)會(huì)和發(fā)送信息的版本號(hào)同步.他們初始值都為-1。

6.2 然后思考一些問(wèn)題

  • a.liveData如何實(shí)現(xiàn)訂閱者模式,如何處理發(fā)送事件?
  • b.如何做到感知生命周期的,怎么跟 LifecycleOwner 進(jìn)行綁定的?
  • c.LiveData 只在 LifecycleOwner active 狀態(tài)發(fā)送通知,是怎么處理的?
  • d.LiveData 會(huì)自動(dòng)在 DESTROY 的狀態(tài)下取消訂閱,是怎么處理的?
  • e.生命周期變化后數(shù)據(jù)處理流程是怎么樣的?
  • f.為什么觀察者只能與一個(gè)LifecycleOwner綁定,而不是多個(gè)?

07.observe訂閱源碼分析

7.1 首先看看observe方法源碼

  • 直接查看源代碼,如下所示:
    • 當(dāng)前綁定的組件(activity或者fragment)狀態(tài)為DESTROYED的時(shí)候, 則會(huì)忽視當(dāng)前的訂閱請(qǐng)求,也就是忽略owner的注冊(cè);
    • 如果需要與生命周期綁定, 則需要傳入LifecycleOwner對(duì)象, 將我們的LiveData數(shù)據(jù)觀測(cè)者(Observer)包裝注冊(cè)到生命周期的觀測(cè)者中, 就是源碼中創(chuàng)建wrapper對(duì)象過(guò)程;
    • 需要注意的問(wèn)題是,不能添加具有不同生命周期的相同觀察者,否則就會(huì)拋出IllegalArgumentException異常,但是owner可以add多個(gè)Observer;
    • 最后添加一個(gè)LifecycleObserver,它將在LifecycleOwner更改狀態(tài)時(shí)得到通知,并做出及時(shí)的對(duì)應(yīng)更新活動(dòng)。
    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
        //當(dāng)前綁定的組件(activity或者fragment)狀態(tài)為DESTROYED的時(shí)候, 則會(huì)忽視當(dāng)前的訂閱請(qǐng)求
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        //創(chuàng)建生命周期感知的觀察者包裝類(lèi)
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        //如果指定的鍵尚未與某個(gè)值關(guān)聯(lián),則將其與給定的值關(guān)聯(lián)
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        //對(duì)應(yīng)觀察者只能與一個(gè)owner綁定
        if (existing != null && !existing.isAttachedTo(owner)) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if (existing != null) {
            return;
        }
        //lifecycle注冊(cè)
        //添加一個(gè)LifecycleObserver,它將在LifecycleOwner更改狀態(tài)時(shí)得到通知
        owner.getLifecycle().addObserver(wrapper);
    }
    

7.2 看看LifecycleBoundObserver源碼

  • 然后看一下觀察者類(lèi)LifecycleBoundObserver的源代碼
    • LifecycleBoundObserver對(duì)象, 它繼承于ObserverWrapper, 并最終實(shí)現(xiàn)了GenericLifecycleObserver接口;
    • 在發(fā)生狀態(tài)轉(zhuǎn)換事件時(shí),會(huì)調(diào)用onStateChanged方法,在這個(gè)方法中,如果是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 的事件會(huì)自動(dòng)解除跟 owner 的綁定
                removeObserver(mObserver);
                return;
            }
            activeStateChanged(shouldBeActive());
        }
    
        @Override
        boolean isAttachedTo(LifecycleOwner owner) {
            return mOwner == owner;
        }
    
        @Override
        void detachObserver() {
            mOwner.getLifecycle().removeObserver(this);
        }
    }
    
    //抽象類(lèi)
    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);
    }
    
  • 通過(guò)上面的代碼可以發(fā)現(xiàn)什么?
    • GenericLifecycleObserver是一個(gè)接口,ObserverWrapper是一個(gè)抽象類(lèi),而LifecycleBoundObserver則是ObserverWrapper的子類(lèi),并且重寫(xiě)了其中幾個(gè)方法;
    • 在LifecycleBoundObserver的shouldBeActive()方法,在 owner 處于至少是 STARTED 的狀態(tài)下認(rèn)為是 active 狀態(tài);
    • 而且它也實(shí)現(xiàn)了 GenericLifecycleObserver 接口,可以監(jiān)聽(tīng) lifecycle 回調(diào)。在 onStateChanged() 方法里處理了生命周期改變的事件,在這個(gè)方法中,當(dāng)接收到 DESTROYED 的事件會(huì)自動(dòng)解除跟 owner 的綁定;
    • 將下個(gè)流程交給了 activeStateChanged(),這里具體可以看抽象類(lèi)ObserverWrapper中的activeStateChanged源碼;
  • 看一下ObserverWrapper抽象類(lèi)中activeStateChanged方法中,onActive和onInactive分別干什么呢?
    • 對(duì)于onActive方法,當(dāng)活動(dòng)觀察者的數(shù)量從0變?yōu)?時(shí)調(diào)用;對(duì)于onInactive方法,當(dāng)活動(dòng)觀察者的數(shù)量從1變?yōu)?時(shí)調(diào)用
    if (wasInactive && mActive) {
        onActive();
    }
    if (LiveData.this.mActiveCount == 0 && !mActive) {
        onInactive();
    }
    
  • 看一下ObserverWrapper抽象類(lèi)中activeStateChanged方法中,dispatchingValue是干什么呢?
    • 這個(gè)方法在分析下面setValue源碼時(shí)還會(huì)說(shuō)到,具體看下面的介紹!

7.3 看看mObservers.putIfAbsent操作

  • 關(guān)于observe源碼中這一行代碼ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper)作用是什么呢?
    • mObservers.putIfAbsent(observer, wrapper)存入容器中,mObservers.putIfAbsent這個(gè)添加數(shù)據(jù)的方式比較少見(jiàn)。
    • 看了下面源代碼可知,支持鍵值對(duì)存儲(chǔ),用鏈表實(shí)現(xiàn),不是線(xiàn)程安全的。既然這里有存數(shù)據(jù),那肯定有地方會(huì)取數(shù)據(jù)用到,這個(gè)后面會(huì)說(shuō)到……
    //mObservers是一個(gè)集合
    private SafeIterableMap<Observer<T>, ObserverWrapper> mObservers =
                new SafeIterableMap<>();
    
    //在SafeIterableMap類(lèi)中的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 注冊(cè)觀察者流程

  • 那么注冊(cè)觀察者之后的觸發(fā)流程是怎樣的?
    • 調(diào)用 observe() 注冊(cè)后,由于綁定了 owner,所以在 active 的情況下,使用LiveData中setValue發(fā)送數(shù)據(jù),則 Observer 會(huì)立馬接受到該數(shù)據(jù)修改的通知。
    • observe ——> onStateChanged ——> activeStateChanged ——> dispatchingValue ——> considerNotify ——> onChanged
    • 至于最終走到了onChanged方法,這個(gè)方法則是交給外部開(kāi)發(fā)者處理接收消息事件的邏輯

08.setValue發(fā)送源碼分析

8.1 setValue源碼分析

  • LiveData 更新數(shù)據(jù)方式有兩個(gè),一個(gè)是 setValue() 另一個(gè)是 postValue(),這兩個(gè)方法的區(qū)別是,postValue() 在內(nèi)部會(huì)拋到主線(xiàn)程去執(zhí)行更新數(shù)據(jù),因此適合在子線(xiàn)程中使用;而 setValue() 則是直接更新數(shù)據(jù)。
    @MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        // 這里的 mVersion,它本問(wèn)題關(guān)鍵,每次更新數(shù)據(jù)都會(huì)自增,默認(rèn)值是 -1。
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }
    
  • 跟進(jìn)下 dispatchingValue() 方法,注意,這里需要重點(diǎn)看considerNotify代碼:
    private void dispatchingValue(@Nullable ObserverWrapper initiator) {
        // mDispatchingValue的判斷主要是為了解決并發(fā)調(diào)用dispatchingValue的情況
        // 當(dāng)對(duì)應(yīng)數(shù)據(jù)的觀察者在執(zhí)行的過(guò)程中, 如有新的數(shù)據(jù)變更, 則不會(huì)再次通知到觀察者。所以觀察者內(nèi)的執(zhí)行不應(yīng)進(jìn)行耗時(shí)工作
        if (mDispatchingValue) {
            //給分發(fā)失敗打個(gè)標(biāo)記
            mDispatchInvalidated = true;
            return;
        }
        // 標(biāo)記分發(fā)開(kāi)始
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            //這里需要注意:區(qū)分ObserverWrapper對(duì)象為空,和不為空的邏輯是不一樣的
            if (initiator != null) {
                // 等下重點(diǎn)看這里的代碼
                considerNotify(initiator);
                initiator = null;
            } else {
                //可以發(fā)現(xiàn)這里用到mObservers集合,使用迭代器遍歷數(shù)據(jù)
                for (Iterator<Map.Entry<Observer<T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    // 等下重點(diǎn)看這里的代碼
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        // 標(biāo)記分發(fā)開(kāi)始
        mDispatchingValue = false;
    }
    
  • 接下來(lái)看一下上面源碼中initiator對(duì)象為空判斷邏輯區(qū)別
    • dispatchingValue 這里分兩種情況:ObserverWrapper不為null和ObserverWrapper為null
    • ObserverWrapper不為null 的情況。LifecycleBoundObserver.onStateChanged 方法里調(diào)用了 activeStateChanged ,而該方法調(diào)用dispatchingValue(this);傳入了 this ,也就是 LifecycleBoundObserver ,這時(shí)候不為 null 。也就是說(shuō)生命周期改變觸發(fā)的流程就是這種情況,這種情況下,只會(huì)通知跟該 Owner 綁定的 Observer。
    • ObserverWrapper為null 的情況。經(jīng)過(guò)分析發(fā)現(xiàn)在setValue方法中調(diào)用dispatchingValue(null)傳遞了空對(duì)象,這個(gè)時(shí)候的流程則會(huì)通知 active 的mObservers

8.2 看一下considerNotify()做什么

  • 然后看一下considerNotify() 方法做了什么,代碼如下所示,這里有道詞典翻譯下注釋
    • 如果ObserverWrapper的mLastVersion小于LiveData的mVersion,就會(huì)去回調(diào)mObserver的onChanged方法。
    • 每個(gè)新的訂閱者,其version都是-1,LiveData一旦設(shè)置過(guò)其version是大于-1的(每次LiveData設(shè)置值都會(huì)使其version加1),這樣就會(huì)導(dǎo)致LiveDataBus每注冊(cè)一個(gè)新的訂閱者,這個(gè)訂閱者立刻會(huì)收到一個(gè)回調(diào),即使這個(gè)設(shè)置的動(dòng)作發(fā)生在訂閱之前。
    private void considerNotify(ObserverWrapper observer) {
        if (!observer.mActive) {
            return;
        }
        // 檢查最新的狀態(tài)b4調(diào)度。也許它改變了狀態(tài),但我們還沒(méi)有得到事件。
        // 我們還是先檢查觀察者?;顒?dòng),以保持它作為活動(dòng)的入口。
        // 因此,即使觀察者移動(dòng)到一個(gè)活動(dòng)狀態(tài),如果我們沒(méi)有收到那個(gè)事件,我們最好不要通知一個(gè)更可預(yù)測(cè)的通知順序。
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        
        //注意認(rèn)真看下面的代碼
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        //noinspection unchecked
        observer.mObserver.onChanged((T) mData);
    }
    
  • 思考一下dispatchingValue除了setValue會(huì)調(diào)用,其他還有地方調(diào)用么?
    • dispatchingValue除了在我們主動(dòng)更新數(shù)據(jù)的時(shí)候會(huì)觸發(fā),
    • 當(dāng)LifeCircleOwner的狀態(tài)發(fā)生變化的時(shí)候,會(huì)調(diào)用LiveData.ObserverWrapper的activeStateChanged函數(shù)。
    • 在我們的觀察者狀態(tài)變更(inactive->active)的時(shí)候, 也會(huì)通知到, 這就導(dǎo)致了LiveData必然支持粘性事件。
    • 如果這個(gè)時(shí)候ObserverWrapper的狀態(tài)是active,就會(huì)調(diào)用LiveData的dispatchingValue。
    • 它主要是處理分發(fā)通知邏輯,并且在分發(fā)通知前會(huì)判斷 owner 的狀態(tài),再加上 LiveData 本身內(nèi)部的版本管理,確保了只會(huì)發(fā)送最新的數(shù)據(jù)給 active 狀態(tài)下的 Observer。
    • LiveData 對(duì)同時(shí)多次修改數(shù)據(jù)做了處理,如果同時(shí)多次修改,只會(huì)修改為最新的數(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的時(shí)候走以下流程
            // 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的時(shí)候,需要通知到觀察者
            if (mActive) {
                dispatchingValue(this);
            }
        }
    }
    

8.3 發(fā)送消息事件流程

  • 那么發(fā)送消息事件之后的觸發(fā)流程是怎樣的?
    • setValue ——> dispatchingValue(null) ——> considerNotify(注意,這里是個(gè)for迭代器循環(huán),表示通知所有觀察者) ——> onChanged

09.observeForever源碼

  • 這個(gè)方法是干什么用的呢?看一下源代碼
    • 將給定的觀察者添加到觀察者列表中,意味著給定的觀察者將接收所有事件,并且永遠(yuǎn)不會(huì)被自動(dòng)刪除,不管在什么狀態(tài)下都能接收到數(shù)據(jù)的更改通知
    @MainThread
    public void observeForever(@NonNull Observer<T> observer) {
        // 創(chuàng)建一個(gè)AlwaysActiveObserver對(duì)象
        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)動(dòng)生命周期, 也可以不聯(lián)動(dòng)。在聯(lián)動(dòng)生命周期時(shí),會(huì)自動(dòng)在 DESTROYED 的狀態(tài)下移除 Observer ,取消訂閱,所以不用擔(dān)心內(nèi)存泄露;
  • LiveData的觀察者只能與一個(gè)LifecycleOwner綁定, 否則會(huì)拋出異常。而一個(gè) owner 可以綁定多個(gè) Observer 實(shí)例;
  • LiveData 跟 LifecycleOwner 綁定,能感知生命周期變化,并且只會(huì)在 LifecycleOwner 處于 Active 狀態(tài)(STARTED/RESUMED)下通知數(shù)據(jù)改變;如果數(shù)據(jù)改變發(fā)生在非 active 狀態(tài),數(shù)據(jù)會(huì)變化,但是不發(fā)送通知,等 owner 回到 active 的狀態(tài)下,再發(fā)送通知;
  • 使用observeForever()方法,會(huì)注意AlwaysActiveObserver對(duì)象,意味著給定的觀察者將接收所有事件,并且永遠(yuǎn)不會(huì)被自動(dòng)刪除,不管在什么狀態(tài)下都能接收到數(shù)據(jù)的更改通知
  • LiveData 利用版本管理、綁定 Lifecycle 確保了只會(huì)發(fā)送最新的數(shù)據(jù)給 active 狀態(tài)下的 Observer
  • image
  • image

參考博客

開(kāi)源LiveData事件總線(xiàn):https://github.com/yangchong211/YCLiveDataBus

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

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

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