Android Architecture Component源碼解析之LiveData

目錄

源碼解析目錄

前言

Android應用開發(fā)的一大問題就是架構缺失,至少我觀察到的是這樣的。我覺得不能苛責說這是程序員水平的問題,Android本身也有它的問題。Android誕生已經超過十年了,但是Android平臺并沒有給我們提供一種簡單明了易用的方案,來解決代碼放哪這么一個基本的問題。所以,造成的結果就是不知道放哪那就往四大組件里面堆吧,堆得太多了,那就寫個Util類吧,僅此而已。
Google估計也是發(fā)現(xiàn)了這種問題,在2017年推出了官方架構,AAC。雖然說有些晚,但是效果還是很顯著的,讓Android應用開發(fā)一下子從刀耕火種的原始社會,直接來到了現(xiàn)代化社會。不得不說,Google一出手,就知道有沒有。Google I/O 2019上公布的數(shù)據(jù)說,Google Play上的Top 1000應用中有80%采用了AAC架構。足可見AAC的受歡迎程度。

問題

數(shù)據(jù)是如何傳輸?shù)氖侨魏渭軜嫷年P鍵環(huán)節(jié),而AAC架構的數(shù)據(jù)傳輸就是依靠LiveData。LiveData可謂是為Android量身定做的數(shù)據(jù)傳輸方案,它不僅解決了數(shù)據(jù)如何傳輸?shù)膯栴},又解決了Android平臺生命周期復雜性的問題。LiveData“神奇”的一點就在于它是可感知生命周期的,onStart之后觀察者才會被通知,onDestroy的時候觀察者又會被自動移除,最大程度上避免了null指針和內存泄漏。這就是我們要在LiveData源碼中尋找的答案,這一切是怎么實現(xiàn)的。(源碼版本androidx.lifecycle:lifecycle-livedata:2.2.0

1. LiveData的職責

LiveData應該完成哪些職責呢?無外這幾點:

  1. 添加包含LifecycleOwner的觀察者
  2. 在LifecycleOwner的ON_DESTROY事件時,移除觀察者
  3. LiveData的數(shù)據(jù)變化后,是否通知觀察者(觀察者可能未處于STARTED或者RESUMED狀態(tài))
  4. 生命周期狀態(tài)變化時,是否通知觀察者(可能此時生命周期來到了STARTED或者RESUMED狀態(tài),之前又積壓了未通知的數(shù)據(jù))
  5. 通知觀察者,并且避免重復通知

LiveData源碼的主要內容就是處理這些問題。

2. LiveData添加觀察者

為LiveData添加帶LifecycleOwner的觀察者的方式特別簡單,調用其observe方法即可:

public abstract class LiveData<T> {
    /**
     * LiveData的觀察者集合,以鍵值對的形式被添加進去,
     * 原始觀察者Observer是鍵,對Observer的包裝類ObserverWrapper是值。
     * SafeIterableMap是支持庫內部實現(xiàn)的一種數(shù)據(jù)結構,底部以鏈表實現(xiàn),表面上看上去卻像個Map
     */
    private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
            new SafeIterableMap<>();
            
    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        //如果Lifecycle已經處于DESTROYED狀態(tài),直接返回
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        //對我們提供的observer進行包裝,看包裝類的名字 LifecycleBoundObserver 就知道,
        // 要包裝成一個跟生命周期關聯(lián)的觀察者類
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        
        //mObservers是LiveData觀察者的集合
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        //不允許相同的owner,observer組合重復添加
        if (existing != null && !existing.isAttachedTo(owner)) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if (existing != null) {
            return;
        }
        //我們的包裝類LifecycleBoundObserver還是LifecycleEventObserver
        //它也被添加到了Lifecycle的觀察者中
        owner.getLifecycle().addObserver(wrapper);
    }
}

//LiveData觀察者的定義
public interface Observer<T> {
    void onChanged(T t);
}

代碼不多,包含的東西不少。我們提供的觀察者observer,在被包裝之后,既被添加到了LiveData的觀察者集合中,又被添加到了了Lifecycle的觀察者集合中。這至少保證了兩件事:第一,LiveData的數(shù)據(jù)變化后,observer可以收到通知;第二,生命周期狀態(tài)變化時,observer可以收到通知。即LiveData職責的第3、第4兩點。
LiveData本身定義的觀察者Observer是很簡單的,只有一個onChanged方法,在LiveData數(shù)據(jù)發(fā)生變化時被調用。但是,如前所述,LiveData最大的特點就是,它與生命周期的緊密關聯(lián)。其observe方法包含兩個參數(shù),LifecycleOwnerObserver,每個Observer還附帶了一個生命周期的擁有者LifecycleOwner。為了完成前面說的職責3和職責4,需要對Observer進行包裝,以為其增加更多狀態(tài),所以才有了ObserverWrapper,LifecycleBoundObserver。

public abstract class LiveData<T> {
    static final int START_VERSION = -1;
    
    //有多少LiveData的觀察者處于“活動”狀態(tài)
    int mActiveCount = 0;
    
    private abstract class ObserverWrapper {
        //被包裝者,即LiveData原始的觀察者
        final Observer<? super T> mObserver;
        //觀察者是否處于“活動”狀態(tài);為原始觀察者mObserver增加屬性,這也是包裝類的意義
        boolean mActive;
        //每個ObserverWrapper初始時version都被設置為了START_VERSION
        int mLastVersion = START_VERSION;

        ObserverWrapper(Observer<? super T> observer) {
            mObserver = observer;
        }

        abstract boolean shouldBeActive();

        boolean isAttachedTo(LifecycleOwner owner) {
            return false;
        }

        void detachObserver() {
        }

        /**
         * ObserverWrapper的主要職責就是:接收來自外部的activeState狀態(tài)的變化,
         * 這里的activeState指的是被包裝者 mObserver 是否處于“活動”狀態(tài)
         * 處于“活動”狀態(tài)的觀察者可以接收LiveData數(shù)據(jù)的變化,否則則不能;
         * 以上所說的活動狀態(tài)指的是當前觀察者的活動狀態(tài),可以理解為 mObserver 的活動狀態(tài),
         * LiveData本身也有活動狀態(tài),當LiveData從“活動”狀態(tài)變?yōu)椤胺腔顒印睜顟B(tài)時,其onActive方法會被調用;
         * 當LiveData從“非活動”狀態(tài)變?yōu)椤盎顒印睜顟B(tài)時,其onInactive方法會被調用;
         * LiveData的活動狀態(tài)取決于它本身的觀察者是否至少有一個處于“活動”狀態(tài)
         */
        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處于活動的觀察者計數(shù)
            LiveData.this.mActiveCount += mActive ? 1 : -1;
            if (wasInactive && mActive) {
                onActive(); //LiveData中的方法,空實現(xiàn)
            }
            if (LiveData.this.mActiveCount == 0 && !mActive) {
                onInactive(); //LiveData中的方法,空實現(xiàn)
            }
            if (mActive) {
                //LiveData中的方法,每當觀察者來的“活動”狀態(tài)時,就會分發(fā)LiveData中的數(shù)據(jù),
                //至于observer中的onChanged方法會不會被調用,還有別的判斷,之后再看
                dispatchingValue(this);
            }
        }
    }
}

ObserverWrapper的主要職責是處理活動狀態(tài)的變化,這種活動狀態(tài)包括觀察者的活動狀態(tài),和LiveData的活動狀態(tài)(注意區(qū)分兩者)。

在本文中,活動狀態(tài)指的是一種狀態(tài),有兩種情況,“活動”和“非活動”;“活動”狀態(tài)指的是前述狀態(tài)處于“活動”這種情況。

需要注意,activeStateChanged方法是在外部被調用的,也就是說,有地方監(jiān)聽狀態(tài)的變化,并負責通知ObserverWrapper,我們之后會看到。

再來看看對ObserverWrapper進一步的包裝LifecycleBoundObserver:

public abstract class LiveData<T> {

    /**
     * 很重要的一點LifecycleBoundObserver實現(xiàn)了LifecycleEventObserver接口,
     * 這個接口是對于生命周期事件的觀察者,詳見Lifcycle源碼解析
     */
    class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
        @NonNull
        final LifecycleOwner mOwner;

        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
            super(observer);
            mOwner = owner;
        }

        //生命周期至少處于STARTED狀態(tài)時,觀察者才是“活動”狀態(tài)
        @Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }

        //該方法是接口LifecycleEventObserver中的方法
        @Override
        public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
            //生命周期來到了DESTROYED,則從LiveData中移除原始的觀察者mObserver
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                //指的是LiveData中的removeObserver方法
                //removeObserver方法會把觀察者從LiveData的觀察者集合中移除,
                //然后還會調用下面的detachObserver方法,從Lifecycle中移除觀察者
                removeObserver(mObserver);
                return;
            }
            //上面提到的ObserverWrapper中的activeStateChanged方法,
            //每當生命周期變化時就調用activeStateChanged
            activeStateChanged(shouldBeActive());
        }

        @Override
        boolean isAttachedTo(LifecycleOwner owner) {
            return mOwner == owner;
        }

        //從生命周期觀察者中移除
        @Override
        void detachObserver() {
            mOwner.getLifecycle().removeObserver(this);
        }
    }
}

先來回顧一下子為LiveData添加一個觀察者的流程,我們的觀察者Observer被包裝成了LifecycleBoundObserver,然后分別被添加到了LiveData的觀察者集合中,和Lifecycle的觀察者中。LifecycleBoundObserver背后其實是兩層包裝,第一層包裝是ObserverWrapper(可以被添加到LiveData的觀察者中),第二層包裝是LifecycleBoundObserver(實現(xiàn)了LifecycleEventObserver,可以被添加到Lifecycle的觀察者中)。

然后再來看LifecycleBoundObserver的源碼,注釋中已經寫得很清楚了,主要就時兩點:

  1. 生命周期變化時通知活動狀態(tài)是否處于“活動”中(處于“活動”狀態(tài)的觀察者,并且之前有“積壓”的數(shù)據(jù)未通知時,觀察者的onChanged方法會被調用)
  2. 生命周期來到DESTROYED時,移除相應觀察者(從LiveData和Lifecycle中)

總結一下,LiveData添加觀察者的內容:

  1. 對Observer進行包裝
  2. 將包裝后的Observer分別添加到LiveData和Lifecycle的觀察者中
  3. 將生命周期的變化轉換為活動狀態(tài)的變化,并且通知觀察者(ObserverWrapper)活動狀態(tài)的變化
  4. 生命周期來到DESTROYED時,移除相應觀察者(從LiveData和Lifecycle中)

LiveData職責的1、2、4條都得到了驗證。下面主要來看LiveData是如何通知觀察者數(shù)據(jù)改變的,并且如何避免重復的通知。也即,LiveData職責的第3、第5兩條。

3. LiveData數(shù)據(jù)的通知

LiveData需要在兩種情況下分發(fā)數(shù)據(jù):

  1. LiveData本身數(shù)據(jù)發(fā)生變化時
  2. 某個觀察者由于生命周期的變化而變成“活動”狀態(tài)時

之所以講分發(fā)數(shù)據(jù),而不是通知數(shù)據(jù)的變化,是因為真正的通知數(shù)據(jù)的變化還取決于其他因素,例如,觀察者是否處于“活動”狀態(tài),觀察者是否已經接收過本次的數(shù)據(jù)。

改變LiveData的數(shù)據(jù)需要使用其setValue或者postValue方法,取決于是否在主線程修改數(shù)據(jù):

public abstract class LiveData<T> {
    //數(shù)據(jù)鎖
    final Object mDataLock = new Object();
    static final int START_VERSION = -1;
    //初始時下LiveData處于未設置狀態(tài)
    static final Object NOT_SET = new Object();

    //LiveData真正的Data,LiveData的數(shù)據(jù)
    private volatile Object mData;
    //通過postValue設置數(shù)據(jù)
    volatile Object mPendingData = NOT_SET;
    //LiveData的數(shù)據(jù)version,用于與觀察者的version進行比較,避免重復通知
    private int mVersion;

    private boolean mDispatchingValue;
    private boolean mDispatchInvalidated;
    
    private final Runnable mPostValueRunnable = new Runnable() {
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            //noinspection unchecked
            setValue((T) newValue);
        }
    };

    /**
     * 使用給定value對LiveData初始化
     */
    public LiveData(T value) {
        mData = value;
        mVersion = START_VERSION + 1;
    }

    /**
     * 默認初始化
     */
    public LiveData() {
        mData = NOT_SET;
        mVersion = START_VERSION;
    }
    
    protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        //切換到主線程去設置數(shù)據(jù),ArchTaskExecutor是AAC中使用的線程池,Room也在使用
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }
    
    @MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        //version增加
        mVersion++;
        mData = value;
        //分發(fā)數(shù)據(jù)的變化
        dispatchingValue(null);
    }
}

可以看出postValue方法最終還是調用的setValue方法,setValue方法也很簡單,增加版本號,設置數(shù)據(jù),并且分發(fā)數(shù)據(jù)。
我們來跟進一下dispatchingValue方法:

public abstract class LiveData<T> {
    //initiator如果為null,證明是LiveData的數(shù)據(jù)發(fā)生了變化,要對所有觀察者分發(fā)數(shù)據(jù),
    //如果initiator不為null,那說明是因為這個initiator代表的觀察者變?yōu)椤盎顒印睜顟B(tài),只需要通知這個initiator本身就可以了
    void dispatchingValue(@Nullable ObserverWrapper initiator) {
        //mDispatchingValue和mDispatchInvalidated兩個標志是為了防止在數(shù)據(jù)分發(fā)的時候,LiveData的數(shù)據(jù)再次發(fā)生變化;
        //例如,某個觀察者onChanged方法內部又調用了setValue方法
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            if (initiator != null) {
                considerNotify(initiator); //只通知initiator本身
                initiator = null;
            } else {
                for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }
    
    private void considerNotify(ObserverWrapper observer) {
        if (!observer.mActive) { //非“活動”狀態(tài)的observer不通知數(shù)據(jù)的變化
            return;
        }
        // Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
        //
        // we still first check observer.active to keep it as the entrance for events. So even if
        // the observer moved to an active state, if we've not received that event, we better not
        // notify for a more predictable notification order.
        // 這個判斷我沒有看懂,包括上面的注解本身我也沒有看懂,留作一個疑問,有明白的還望告知
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        //觀察者的version不小于LiveData的version,說明該觀察者已經被通知過了,不再通知
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        //終于看到了我們observer的onChanged方法被調用
        observer.mObserver.onChanged((T) mData);
    }
}

LiveData數(shù)據(jù)分發(fā)的脈絡還是很清晰的,因為LiveData數(shù)據(jù)發(fā)生變化的,對所有觀察者考慮是否通知數(shù)據(jù)的變化;因為某個觀察者變?yōu)椤盎顒印睜顟B(tài)的,只對該觀察者本身考慮是否通知數(shù)據(jù)的變化。并且通過比較LiveData和觀察者(ObserverWrapper)的版本號,來避免重復的通知。LiveData職責的第3、第5兩條也得到了驗證。


到這里,關于LiveData的源碼基本上是分析完了,其中省略了如下一些內容:

  1. LiveData移除觀察者
  2. 為LiveData添加“永久”的觀察者(observeForever方法),說是“永久”的觀察者,其實就是沒有綁定生命周期的觀察者,也可以手動移除。
  3. MutableLiveData

這些內容比較簡單,在此略過。

4. LiveData的轉換Transformations

上文提到了LiveData的onActiveonInactive方法,分別在LiveData變?yōu)椤盎顒印焙妥優(yōu)椤胺腔顒印睍r被調用,但是在LiveData本身的實現(xiàn)中,onActiveonInactive均為空實現(xiàn)。其實,單對于觀察LiveData數(shù)據(jù)的變化而言,確實沒有必要實現(xiàn)LiveData本身的活動狀態(tài)的變化,這兩個方法主要是用來自定義LiveData或者對LiveData進行轉換的。具體使用場景見Google文檔。下面具體分析一下LiveData的轉換。

最簡單的LiveData的轉換的例子就是map,就像RxJava中的map那樣。LiveData實現(xiàn)轉換的關鍵是MediatorLiveData類:

//類如其名,中介者LiveData
public class MediatorLiveData<T> extends MutableLiveData<T> {
    private SafeIterableMap<LiveData<?>, Source<?>> mSources = new SafeIterableMap<>();

    /**
     * 添加作為“源”的LiveData,和對“源”的LiveData的觀察者
     * 當“源”LiveData數(shù)據(jù)變化,并且當前MediatorLiveData處于“活動”狀態(tài)(擁有“活動”觀察者)時,onChanged就會被調用
     * 實際上正如類名一樣,這實際上起到了中介者的作用,MediatorLiveData傳遞了“源”LiveData的數(shù)據(jù)變化,同時我們又可以在onChanged中對“源”LiveData的數(shù)據(jù)進行轉換
     */
    @MainThread
    public <S> void addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged) {
        Source<S> e = new Source<>(source, onChanged);
        Source<?> existing = mSources.putIfAbsent(source, e);
        if (existing != null && existing.mObserver != onChanged) {
            throw new IllegalArgumentException(
                    "This source was already added with the different observer");
        }
        if (existing != null) {
            return;
        }
        if (hasActiveObservers()) {
            e.plug();
        }
    }

    /**
     * 移除“源”LiveData
     */
    @MainThread
    public <S> void removeSource(@NonNull LiveData<S> toRemote) {
        Source<?> source = mSources.remove(toRemote);
        if (source != null) {
            source.unplug();
        }
    }

    @CallSuper
    @Override
    protected void onActive() {
        for (Map.Entry<LiveData<?>, Source<?>> source : mSources) {
            source.getValue().plug();
        }
    }

    @CallSuper
    @Override
    protected void onInactive() {
        for (Map.Entry<LiveData<?>, Source<?>> source : mSources) {
            source.getValue().unplug();
        }
    }

    private static class Source<V> implements Observer<V> {
        final LiveData<V> mLiveData;
        final Observer<? super V> mObserver;
        int mVersion = START_VERSION;

        Source(LiveData<V> liveData, final Observer<? super V> observer) {
            mLiveData = liveData;
            mObserver = observer;
        }

        void plug() {
            mLiveData.observeForever(this);
        }

        void unplug() {
            mLiveData.removeObserver(this);
        }

        @Override
        public void onChanged(@Nullable V v) {
            if (mVersion != mLiveData.getVersion()) {
                mVersion = mLiveData.getVersion();
                mObserver.onChanged(v);
            }
        }
    }
}

單看MediatorLiveData可能比較懵逼,沒事,結合map等轉換一起看就明白什么意思了。

public class Transformations {

    private Transformations() {
    }

    /**
     * 最簡單明了的轉換操作
     * 傳入source “源”LiveData,將其轉換為另一種類型的LiveData
     * LiveData<X> -> LiveData<Y>
     */
    @MainThread
    @NonNull
    public static <X, Y> LiveData<Y> map(
            @NonNull LiveData<X> source,
            @NonNull final Function<X, Y> mapFunction) {
        final MediatorLiveData<Y> result = new MediatorLiveData<>();
        result.addSource(source, new Observer<X>() {
            @Override
            public void onChanged(@Nullable X x) {
                //source的變化會通知到這個方法,我們用mapFunction對我們接收到的數(shù)據(jù)進行轉換
                result.setValue(mapFunction.apply(x));
            }
        });
        //返回中介 MediatorLiveData
        return result;
    }

    /**
     * 這個方法比較不好理解,可以去看源碼中的注釋幫助理解
     */
    @MainThread
    @NonNull
    public static <X, Y> LiveData<Y> switchMap(
            @NonNull LiveData<X> source,
            @NonNull final Function<X, LiveData<Y>> switchMapFunction) {
        final MediatorLiveData<Y> result = new MediatorLiveData<>();
        result.addSource(source, new Observer<X>() {
            LiveData<Y> mSource;

            @Override
            public void onChanged(@Nullable X x) {
                LiveData<Y> newLiveData = switchMapFunction.apply(x);
                if (mSource == newLiveData) {
                    return;
                }
                if (mSource != null) {
                    result.removeSource(mSource);
                }
                mSource = newLiveData;
                if (mSource != null) {
                    result.addSource(mSource, new Observer<Y>() {
                        @Override
                        public void onChanged(@Nullable Y y) {
                            result.setValue(y);
                        }
                    });
                }
            }
        });
        return result;
    }

    /**
     * 直到source數(shù)據(jù)跟上次的數(shù)據(jù)不同時才通知
     */
    @MainThread
    @NonNull
    public static <X> LiveData<X> distinctUntilChanged(@NonNull LiveData<X> source) {
        final MediatorLiveData<X> outputLiveData = new MediatorLiveData<>();
        outputLiveData.addSource(source, new Observer<X>() {

            boolean mFirstTime = true;

            @Override
            public void onChanged(X currentValue) {
                final X previousValue = outputLiveData.getValue();
                if (mFirstTime
                        || (previousValue == null && currentValue != null)
                        || (previousValue != null && !previousValue.equals(currentValue))) {
                    mFirstTime = false;
                    outputLiveData.setValue(currentValue);
                }
            }
        });
        return outputLiveData;
    }
}

最初的Transformations類只有map這一個方法,現(xiàn)在又增加了兩個,源碼也不難理解,核心思想都是拿到“源”LiveData的數(shù)據(jù),然后對數(shù)據(jù)做轉換后,再設置給MediatorLiveData,這樣通過MediatorLiveData,轉換就完成了。

可以看出,LiveData是想模仿RxJava那樣的操作符的,但是,LiveData的設計思想跟RxJava差別還是很大的,能實現(xiàn)的操作符非常有限。Transformations的主要作用是,正確傳遞“源”LiveData的數(shù)據(jù)變化,并且保證觀察者的生命周期變化能傳遞給“源”LiveData。說白了,就是讓MediatorLiveData沒有存在感。

5. 隱藏技能

  1. 如果我們的觀察者處于“非活動”狀態(tài),他變?yōu)椤盎顒印睜顟B(tài)后只會收到最新的數(shù)據(jù),也就是說LiveData的數(shù)據(jù)是會“折疊”的。
  2. 除非你人為的去設置LiveData的數(shù)據(jù)為null(setValue(null)或者postValue(null)),否則在Observer的onChanged方法中接收到的數(shù)據(jù)是不可能為null的。如果使用第三方庫提供的某些LiveData,在onChanged中判空是有必要的,說不定它用null代表什么特殊的含義。

6. 總結

我們的觀察者經過包裝后,被添加進LiveData的觀察者集合,同時,也被添加到了我們提供的Lifecycle的觀察者集合中(如果我們提供了LifecycleOwner的話),這樣,無論是LiveData本身的數(shù)據(jù)發(fā)生變化,還是觀察者變?yōu)椤盎顒印睜顟B(tài)時,我們的觀察者都會被cue到。但是,只有當我們的觀察者處于“活動”狀態(tài)并且沒有被通知過的時候(version低于LiveData的version),Observer的onChanged方法才會被調用。

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

相關閱讀更多精彩內容

友情鏈接更多精彩內容