LiveData詳細分析

目錄介紹

  • 01.LiveData是什麼東西
  • 02.使用LiveData的優點
  • 03.使用LiveData的步驟
  • 04.簡單使用LiveData
  • 05.observe()和observerForever()
  • 06.LiveData原理介紹
  • 07.observe訂閱源碼分析
  • 08.setValue發送源碼分析
  • 09.observeForever源碼
  • 10.LiveData源碼總結

00.使用LiveData實現bus事件總線

  • 利用LiveData實現事件總線,替代EventBus。充分利用了生命週期感知功能,能夠在activities, fragments, 或者 services生命週期是活躍狀態時更新這些組件。支持發送普通事件,也能夠發送粘性事件;還能夠發送延遲消息,以及輪訓延遲消息等等。
  • github.com/yangchong21…

01.LiveData是什麼東西

  • 基於觀察者模式
    • LiveData是一種持有可被觀察數據的類。LiveData須要一個觀察者對象,通常是Observer類的具體實現。當觀察者的生命週期處於STARTED或RESUMED狀態時,LiveData會通知觀察者數據變化。
  • 感知生命週期
    • 和其餘可被觀察的類不一樣的是,LiveData是有生命週期感知能力的,這意味着它能夠在activities, fragments, 或者 services生命週期是活躍狀態時更新這些組件。那麼什麼是活躍狀態呢?就是STARTED和RESUMED就是活躍狀態,只有在這兩個狀態下LiveData是會通知數據變化的。
  • 自動解除數據訂閱
    • 要想使用LiveData(或者這種有可被觀察數據能力的類)就必須配合實現了LifecycleOwner的對象使用。在這種狀況下,當對應的生命週期對象DESTORY時,才能移除觀察者。這對Activity或者Fragment來講顯得尤其重要,由於他們能夠在生命週期結束的時候馬上解除對數據的訂閱,從而避免內存泄漏等問題。

02.使用LiveData的優點

2.1 具備很明顯的優勢

  • UI和實時數據保持一致
    • 由於LiveData採用的是觀察者模式,這樣一來就能夠在數據發生改變時得到通知,更新UI。
  • 不會發生內存泄露
    • 觀察者被綁定到組件的生命週期上,當被綁定的組件銷燬(onDestroy)時,觀察者會馬上自動清理自身的數據。
  • 不會再產生因爲Activity處於stop狀態而引發的崩潰
    • 例如:當Activity處於後臺狀態時,是不會收到LiveData的任何事件的。
  • 不須要再解決生命週期帶來的問題
    • LiveData能夠感知被綁定的組件的生命週期,只有在活躍狀態纔會通知數據變化。
  • 實時數據刷新
    • 當組件處於活躍狀態或者從不活躍狀態到活躍狀態時老是能收到最新的數據
  • 解決Configuration Change問題
    • 在屏幕發生旋轉或者被回收再次啓動,馬上就能收到最新的數據。
  • 數據共享
    • 若是對應的LiveData是單例的話,就能在app的組件間分享數據。這部分詳細的信息能夠參考繼承LiveData

2.2 細節點補充

  • 組件和數據相關的內容能實時更新,組件在前臺的時候可以實時收到數據改變的通知,當組件從後臺到前臺來時,LiveData可以將最新的數據通知組件,所以保證了組件中和數據相關的內容可以實時更新。
  • 若是橫豎屏切換(configuration change)時,不須要額外的處理來保存數據,當屏幕方向變化時,組件會被recreate,然而系統並不能保證你的數據可以被恢復的。當咱們採用LiveData保存數據時,由於數據和組件分離了。當組件被recreate,數據仍是存在LiveData中,並不會被銷燬。

03.使用LiveData的步驟

  • 建立一個持有某種數據類型的LiveData (一般是在ViewModel中)
  • 建立一個定義了onChange()方法的觀察者。這個方法是控制LiveData中數據發生變化時,採起什麼措施 (好比更新界面)。一般是在UI Controller (Activity/Fragment) 中建立這個觀察者。
  • 經過 observe()方法鏈接觀察者和LiveData。observe()方法須要攜帶一個LifecycleOwner類。這樣就可讓觀察者訂閱LiveData中的數據,實現實時更新。

04.簡單使用LiveData

4.1 單獨使用LiveData

  • 舉一個最簡單的案例代碼:
    liveData = new MutableLiveData<>();
    liveData.observe(this, new Observer<String>() {
        @Override
        public void onChanged(@Nullable final String newText) {
            // 更新數據
            tv3.setText(newText);
        }
    });
    liveData.setValue("小楊真的是一個逗比麼");
    複製代碼
  • 那麼上面這一段代碼大概是什麼意思呢?
    • 首先建立一個 MutableLiveData(LiveData是抽象類)對象 ,經過 observe 方法能夠訂閱修改數據的通知,經過 postValue()或者 setValue() 方法發送事件更新數據,已經訂閱的 Observer 可以獲得數據更改的通知,就會回調 onChanged() 方法。

4.2 使用LiveData配合ViewModel

  • LiveData是一個數據的包裝。具體的包裝對象能夠是任何數據,包括集合。它是一個抽象類,首先先建立一個類實現LiveData。代碼以下所示:
    public class TextViewModel extends ViewModel {
    
        /**
         * LiveData是抽象類,MutableLiveData是具體實現類
         */
        private MutableLiveData<String> mCurrentText;
    
        public MutableLiveData<String> getCurrentText() {
            if (mCurrentText == null) {
                mCurrentText = new MutableLiveData<>();
            }
            return mCurrentText;
        }
    
    }
    複製代碼
  • 建立一個觀察的對象,觀察LiveData中的數據。目前在組件的onCreate()方法中開始觀察數據,代碼以下所示:
    • 思考下,能夠在onResume()中調用麼,我的以爲不太好。由於系統會屢次調用onResume()方法。
    private void initLiveData() {
        // 建立一個持有某種數據類型的LiveData (一般是在ViewModel中)
        model = ViewModelProviders.of(this).get(TextViewModel.class);
        // 建立一個定義了onChange()方法的觀察者
        // 開始訂閱
        final Observer<String> nameObserver = new Observer<String>() {
            @Override
            public void onChanged(@Nullable final String newText) {
                // 更新數據
                tvText.setText(newText);
            }
        };
        // 經過 observe()方法鏈接觀察者和LiveData,注意:observe()方法須要攜帶一個LifecycleOwner類
        model.getCurrentText().observe(this, nameObserver);
    }
    複製代碼
  • 而後去建立更新對象數據內容的對象。如何去更新那個文本中的數據呢?代碼以下所示:
    • 想要在UI Controller中改變LiveData中的值呢?(好比點擊某個Button設置文本內容的更改)。
    • LiveData並無提供這樣的功能,可是Architecture Component提供了MutableLiveData這樣一個類,能夠經過setValue(T)和postValue(T)方法來修改存儲在LiveData中的數據。MutableLiveData是LiveData的一個子類,從名稱上也能看出這個類的做用。
    • 調用setValue()方法就能夠把LiveData中的值改成 "小楊真的是一個逗比麼" 。一樣,經過這種方法修改LiveData中的值一樣會觸發全部對這個數據感興趣的類。那麼setValue()和postValue()有什麼不一樣呢?區別就是setValue()只能在主線程中調用,而postValue()能夠在子線程中調用。
    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 = "開始刷新數據啦";
                    break;
                default:
                    text = "變化成默認的數據";
                    break;
            }
            model.getCurrentText().setValue(text);
        }
    });
    複製代碼

05.observe()和observerForever()

  • 通常咱們使用 LiveData 的 observe(),當數據更新後,LiveData 會通知它的全部活躍的觀察者。
    • 與 RxJava 不一樣的,LiveData 只會通知活躍的觀察者,例如 Activity 位於 Destroyed 狀態時是不活躍的,所以不會收到通知。
  • 固然咱們也可使用 LiveData 的 observerForever() 方法進行訂閱,區別是 observerForever() 不會受到 Activity 等組件的生命週期的影響,只要數據更新就會收到通知。

06.LiveData原理介紹

6.1 簡單的原理介紹

  • LiveData可對數據進行觀測, 並具備生命週期感知能力, 這就意味着當liveData只會在生命週期處於活躍(inActive)的狀態下才會去執行觀測動做, 而他的能力賦予不能脫離LifeCycle的範圍。
  • 須要注意的是,LiveData內維護的mVersion表示的是發送信息的版本,每次發送一次信息, 它都會+1, 而ObserverWrapper內維護的mLastVersion爲訂閱觸發的版本號, 當訂閱動做生效的時候, 它的版本號會和發送信息的版本號同步.他們初始值都爲-1。

6.2 而後思考一些問題

  • a.liveData如何實現訂閱者模式,如何處理髮送事件?
  • b.如何作到感知生命週期的,怎麼跟 LifecycleOwner 進行綁定的?
  • c.LiveData 只在 LifecycleOwner active 狀態發送通知,是怎麼處理的?
  • d.LiveData 會自動在 DESTROY 的狀態下取消訂閱,是怎麼處理的?
  • e.生命週期變化後數據處理流程是怎麼樣的?
  • f.爲何觀察者只能與一個LifecycleOwner綁定,而不是多個?

07.observe訂閱源碼分析

7.1 首先看看observe方法源碼

  • 直接查看源代碼,以下所示:
    • 當前綁定的組件(activity或者fragment)狀態爲DESTROYED的時候, 則會忽視當前的訂閱請求,也就是忽略owner的註冊;
    • 若是須要與生命週期綁定, 則須要傳入LifecycleOwner對象, 將咱們的LiveData數據觀測者(Observer)包裝註冊到生命週期的觀測者中, 就是源碼中建立wrapper對象過程;
    • 須要注意的問題是,不能添加具備不一樣生命週期的相同觀察者,不然就會拋出IllegalArgumentException異常,可是owner能夠add多個Observer;
    • 最後添加一個LifecycleObserver,它將在LifecycleOwner更改狀態時獲得通知,並作出及時的對應更新活動。
    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
        //當前綁定的組件(activity或者fragment)狀態爲DESTROYED的時候, 則會忽視當前的訂閱請求
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        //建立生命週期感知的觀察者包裝類
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        //若是指定的鍵還沒有與某個值關聯,則將其與給定的值關聯
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        //對應觀察者只能與一個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更改狀態時獲得通知
        owner.getLifecycle().addObserver(wrapper);
    }
    複製代碼

7.2 看看LifecycleBoundObserver源碼

  • 而後看一下觀察者類LifecycleBoundObserver的源代碼
    • LifecycleBoundObserver對象, 它繼承於ObserverWrapper, 並最終實現了GenericLifecycleObserver接口;
    • 在發生狀態轉換事件時,會調用onStateChanged方法,在這個方法中,若是是DESTROYED狀態,則先要移除觀察者,而後在取到生命週期狀態變動事件
    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) {
                // 當接收到 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); } 複製代碼
  • 經過上面的代碼能夠發現什麼?
    • GenericLifecycleObserver是一個接口,ObserverWrapper是一個抽象類,而LifecycleBoundObserver則是ObserverWrapper的子類,而且重寫了其中幾個方法;
    • 在LifecycleBoundObserver的shouldBeActive()方法,在 owner 處於至少是 STARTED 的狀態下認爲是 active 狀態;
    • 並且它也實現了 GenericLifecycleObserver 接口,能夠監聽 lifecycle 回調。在 onStateChanged() 方法裏處理了生命週期改變的事件,在這個方法中,當接收到 DESTROYED 的事件會自動解除跟 owner 的綁定;
    • 將下個流程交給了 activeStateChanged(),這裏具體能夠看抽象類ObserverWrapper中的activeStateChanged源碼;
  • 看一下ObserverWrapper抽象類中activeStateChanged方法中,onActive和onInactive分別幹什麼呢?
    • 對於onActive方法,當活動觀察者的數量從0變爲1時調用;對於onInactive方法,當活動觀察者的數量從1變爲0時調用
    if (wasInactive && mActive) {
        onActive();
    }
    if (LiveData.this.mActiveCount == 0 && !mActive) {
        onInactive();
    }
    複製代碼
  • 看一下ObserverWrapper抽象類中activeStateChanged方法中,dispatchingValue是幹什麼呢?
    • 這個方法在分析下面setValue源碼時還會說到,具體看下面的介紹!

7.3 看看mObservers.putIfAbsent操做

  • 關於observe源碼中這一行代碼ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper)做用是什麼呢?
    • mObservers.putIfAbsent(observer, wrapper)存入容器中,mObservers.putIfAbsent這個添加數據的方式比較少見。
    • 看了下面源代碼可知,支持鍵值對存儲,用鏈表實現,不是線程安全的。既然這裏有存數據,那確定有地方會取數據用到,這個後面會說到……
    //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 註冊觀察者流程

  • 那麼註冊觀察者以後的觸發流程是怎樣的?
    • 調用 observe() 註冊後,因爲綁定了 owner,因此在 active 的狀況下,使用LiveData中setValue發送數據,則 Observer 會立馬接受到該數據修改的通知。
    • observe ——> onStateChanged ——> activeStateChanged ——> dispatchingValue ——> considerNotify ——> onChanged
    • 至於最終走到了onChanged方法,這個方法則是交給外部開發者處理接收消息事件的邏輯

08.setValue發送源碼分析

8.1 setValue源碼分析

  • LiveData 更新數據方式有兩個,一個是 setValue() 另外一個是 postValue(),這兩個方法的區別是,postValue() 在內部會拋到主線程去執行更新數據,所以適合在子線程中使用;而 setValue() 則是直接更新數據。
    @MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        // 這裏的 mVersion,它本問題關鍵,每次更新數據都會自增,默認值是 -1。
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }
    複製代碼
  • 跟進下 dispatchingValue() 方法,注意,這裏須要重點看considerNotify代碼:
    private void dispatchingValue(@Nullable ObserverWrapper initiator) {
        // mDispatchingValue的判斷主要是爲了解決併發調用dispatchingValue的狀況
        // 當對應數據的觀察者在執行的過程當中, 若有新的數據變動, 則不會再次通知到觀察者。因此觀察者內的執行不該進行耗時工做
        if (mDispatchingValue) {
            //給分發失敗打個標記
            mDispatchInvalidated = true;
            return;
        }
        // 標記分發開始
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            //這裏須要注意:區分ObserverWrapper對象爲空,和不爲空的邏輯是不同的
            if (initiator != null) {
                // 等下重點看這裏的代碼
                considerNotify(initiator);
                initiator = null;
            } else {
                //能夠發現這裏用到mObservers集合,使用迭代器遍歷數據
                for (Iterator<Map.Entry<Observer<T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    // 等下重點看這裏的代碼
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        // 標記分發開始
        mDispatchingValue = false;
    }
    複製代碼
  • 接下來看一下上面源碼中initiator對象爲空判斷邏輯區別
    • dispatchingValue 這裏分兩種狀況:ObserverWrapper不爲null和ObserverWrapper爲null
    • ObserverWrapper不爲null 的狀況。LifecycleBoundObserver.onStateChanged 方法裏調用了 activeStateChanged ,而該方法調用dispatchingValue(this);傳入了 this ,也就是 LifecycleBoundObserver ,這時候不爲 null 。也就是說生命週期改變觸發的流程就是這種狀況,這種狀況下,只會通知跟該 Owner 綁定的 Observer。
    • ObserverWrapper爲null 的狀況。通過分析發如今setValue方法中調用dispatchingValue(null)傳遞了空對象,這個時候的流程則會通知 active 的mObservers

8.2 看一下considerNotify()作什麼

  • 而後看一下considerNotify() 方法作了什麼,代碼以下所示,這裏有道詞典翻譯下注釋
    • 若是ObserverWrapper的mLastVersion小於LiveData的mVersion,就會去回調mObserver的onChanged方法。
    • 每一個新的訂閱者,其version都是-1,LiveData一旦設置過其version是大於-1的(每次LiveData設置值都會使其version加1),這樣就會致使LiveDataBus每註冊一個新的訂閱者,這個訂閱者馬上會收到一個回調,即便這個設置的動做發生在訂閱以前。
    private void considerNotify(ObserverWrapper observer) {
        if (!observer.mActive) {
            return;
        }
        // 檢查最新的狀態b4調度。也許它改變了狀態,但咱們尚未獲得事件。
        // 咱們仍是先檢查觀察者。活動,以保持它做爲活動的入口。
        // 所以,即便觀察者移動到一個活動狀態,若是咱們沒有收到那個事件,咱們最好不要通知一個更可預測的通知順序。
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        
        //注意認真看下面的代碼
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        //noinspection unchecked
        observer.mObserver.onChanged((T) mData);
    }
    複製代碼
  • 思考一下dispatchingValue除了setValue會調用,其餘還有地方調用麼?
    • dispatchingValue除了在咱們主動更新數據的時候會觸發,
    • 當LifeCircleOwner的狀態發生變化的時候,會調用LiveData.ObserverWrapper的activeStateChanged函數。
    • 在咱們的觀察者狀態變動(inactive->active)的時候, 也會通知到, 這就致使了LiveData必然支持粘性事件。
    • 若是這個時候ObserverWrapper的狀態是active,就會調用LiveData的dispatchingValue。
    • 它主要是處理分發通知邏輯,而且在分發通知前會判斷 owner 的狀態,再加上 LiveData 自己內部的版本管理,確保了只會發送最新的數據給 active 狀態下的 Observer。
    • LiveData 對同時屢次修改數據作了處理,若是同時屢次修改,只會修改成最新的數據。
    private abstract class ObserverWrapper {
        final Observer<T> mObserver;
        boolean mActive;
        int mLastVersion = START_VERSION;
        //省略部分代碼
        void activeStateChanged(boolean newActive) {
            if (newActive == mActive) {
                return;
            }
            // 當observer的狀態從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();
            }
            //當observer是從inactive->active的時候,須要通知到觀察者
            if (mActive) {
                dispatchingValue(this);
            }
        }
    }
    複製代碼

8.3 發送消息事件流程

  • 那麼發送消息事件以後的觸發流程是怎樣的?
    • setValue ——> dispatchingValue(null) ——> considerNotify(注意,這裏是個for迭代器循環,表示通知全部觀察者) ——> onChanged

09.observeForever源碼

  • 這個方法是幹什麼用的呢?看一下源代碼
    • 將給定的觀察者添加到觀察者列表中,意味着給定的觀察者將接收全部事件,而且永遠不會被自動刪除,無論在什麼狀態下都能接收到數據的更改通知
    @MainThread
    public void observeForever(@NonNull Observer<T> observer) {
        // 建立一個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;
        }
        //刷新數據
        wrapper.activeStateChanged(true);
    }
    複製代碼

10.LiveData源碼總結

  • LiveData的觀察者能夠聯動生命週期, 也能夠不聯動。在聯動生命週期時,會自動在 DESTROYED 的狀態下移除 Observer ,取消訂閱,因此不用擔憂內存泄露;
  • LiveData的觀察者只能與一個LifecycleOwner綁定, 不然會拋出異常。而一個 owner 能夠綁定多個 Observer 實例;
  • LiveData 跟 LifecycleOwner 綁定,能感知生命週期變化,而且只會在 LifecycleOwner 處於 Active 狀態(STARTED/RESUMED)下通知數據改變;若是數據改變發生在非 active 狀態,數據會變化,可是不發送通知,等 owner 回到 active 的狀態下,再發送通知;
  • 使用observeForever()方法,會注意AlwaysActiveObserver對象,意味着給定的觀察者將接收全部事件,而且永遠不會被自動刪除,無論在什麼狀態下都能接收到數據的更改通知
  • LiveData 利用版本管理、綁定 Lifecycle 確保了只會發送最新的數據給 active 狀態下的 Observer
  • image
  • image

參考博客

開源LiveData事件總線:github.com/yangchong21…

相關文章
相關標籤/搜索