LiveData源碼

自己看寓盗,如果不對(duì)系馆,請指出像鸡!


package androidx.lifecycle;

import static androidx.lifecycle.Lifecycle.State.DESTROYED;
import static androidx.lifecycle.Lifecycle.State.STARTED;

import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.arch.core.executor.ArchTaskExecutor;
import androidx.arch.core.internal.SafeIterableMap;

import java.util.Iterator;
import java.util.Map;

public abstract class LiveData<T> {
    
    // 用于synchronized同步處理的數(shù)據(jù)對(duì)象
    @SuppressWarnings("WeakerAccess") /* synthetic access */
    final Object mDataLock = new Object();
    
    // 當(dāng)前持有數(shù)據(jù)的版本號(hào)粉渠,默認(rèn)為-1
    static final int START_VERSION = -1;
    
    // 定義當(dāng)mData沒有數(shù)據(jù)時(shí)的默認(rèn)數(shù)據(jù)
    @SuppressWarnings("WeakerAccess") /* synthetic access */
    static final Object NOT_SET = new Object();

    // 用于存儲(chǔ)全部的Observer對(duì)象的安全迭代Map
    // SafeIterableMap一個(gè)能在遍歷中刪除元素的數(shù)據(jù)結(jié)構(gòu)
    private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
            new SafeIterableMap<>();

    // 記錄有多少個(gè)Active狀態(tài)的Observer
    @SuppressWarnings("WeakerAccess") /* synthetic access */
    int mActiveCount = 0;
   
    // 用于處理Active\InActive狀態(tài)
    private boolean mChangingActiveState;
    
    // 真實(shí)數(shù)據(jù)
    private volatile Object mData;
    
    // 當(dāng)setData被調(diào)用, 在主線程進(jìn)行pending數(shù)據(jù)和實(shí)際數(shù)據(jù)的交換
    @SuppressWarnings("WeakerAccess") /* synthetic access */
    volatile Object mPendingData = NOT_SET;
    
    // 當(dāng)前持有數(shù)據(jù)的版本號(hào)
    private int mVersion;

    // 記錄在遍歷通知各ObserverWrapper期間原押,數(shù)據(jù)是否發(fā)生變化
    private boolean mDispatchingValue;
    
    // 記錄判斷是否數(shù)據(jù)分發(fā)無效
    @SuppressWarnings("FieldCanBeLocal")
    private boolean mDispatchInvalidated;
    
    // postValue()函數(shù)調(diào)用的Runnable
    private final Runnable mPostValueRunnable = new Runnable() {
        @SuppressWarnings("unchecked")
        @Override
        public void run() {
            // 定義新的value
            Object newValue;
            // 同步處理
            synchronized (mDataLock) {
                // 新的value設(shè)置為mPendingData
                newValue = mPendingData;
                // mPendingData更新為默認(rèn)數(shù)據(jù)
                mPendingData = NOT_SET;
            }
            // 調(diào)用setValue()
            setValue((T) newValue);
        }
    };

    /**
     * 有參數(shù)的構(gòu)造函數(shù)
     *
     * @param value initial value
     */
    public LiveData(T value) {
        // 實(shí)際數(shù)據(jù)設(shè)置為參數(shù)傳遞的數(shù)據(jù)
        mData = value;
        // 當(dāng)前持有的數(shù)據(jù)版本號(hào)從-1變?yōu)?
        mVersion = START_VERSION + 1;
    }

    /**
     * 無參構(gòu)造函數(shù)
     */
    public LiveData() {
        // 實(shí)際數(shù)據(jù)設(shè)置為默認(rèn)數(shù)據(jù)
        mData = NOT_SET;
        // 當(dāng)前版本設(shè)置為-1
        mVersion = START_VERSION;
    }

    // 實(shí)際更新數(shù)據(jù)的方法胁镐,判斷是否需要將數(shù)據(jù)分發(fā)到指定的ObserverWrapper
    @SuppressWarnings("unchecked")
    private void considerNotify(ObserverWrapper observer) {
        // 判斷指定的observer是否是Active狀態(tài),不是則返回
        if (!observer.mActive) {
            return;
        }
        // 再次確認(rèn)observer的最新狀態(tài)诸衔,因?yàn)橛锌赡苌芷趯?shí)際上已經(jīng)變化了盯漂,但是Active狀態(tài)還沒改變
        if (!observer.shouldBeActive()) {
            // 如果當(dāng)前的observer不是Active狀態(tài),處于InActive狀態(tài)笨农,則不進(jìn)行數(shù)據(jù)分發(fā)就缆,并返回
            observer.activeStateChanged(false);
            return;
        }
        // 判斷observer所持有的的版本是不是最新版本,如果是最新版本谒亦,則返回
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        // 否則observer的版本就是當(dāng)前最新版本
        observer.mLastVersion = mVersion;
        // observer通知新數(shù)據(jù)更新
        observer.mObserver.onChanged((T) mData);
    }

    // 將數(shù)據(jù)通知給observer
    @SuppressWarnings("WeakerAccess") /* synthetic access */
    void dispatchingValue(@Nullable ObserverWrapper initiator) {
        // 如果在遍歷OberverWrapper期間竭宰,如果數(shù)據(jù)發(fā)生改變空郊,則會(huì)重新遍歷通知
        if (mDispatchingValue) {
            // 如果數(shù)據(jù)發(fā)生變化,則分發(fā)無效
            mDispatchInvalidated = true;
            return;
        }
        // 設(shè)置數(shù)據(jù)發(fā)生變化標(biāo)識(shí)為true
        mDispatchingValue = true;
        do {
            // 分發(fā)無效標(biāo)記設(shè)為false
            mDispatchInvalidated = false;
            // 如果傳入的initiator不是空的切揭,就只通知特定的ObserWrapper即可狞甚,如果是空的,就通知所有的
            if (initiator != null) {
                // 進(jìn)行實(shí)際數(shù)據(jù)分發(fā)
                considerNotify(initiator);
                // initiator對(duì)象置空
                initiator = null;
            } else {
                // 遍歷所有的ObserverWrapper對(duì)象
                for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    // 進(jìn)行實(shí)際數(shù)據(jù)分發(fā)
                    considerNotify(iterator.next().getValue());
                    // 如果期間數(shù)據(jù)發(fā)生了變化廓旬,則中斷for循環(huán)數(shù)據(jù)分發(fā)處理
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
            // 如果數(shù)據(jù)無效標(biāo)識(shí)為true哼审,則do...while進(jìn)行重新遍歷,通知ObserWrapper進(jìn)行數(shù)據(jù)分發(fā)
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }

    // 注冊O(shè)bserver
    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        // 判斷是否是主線程嗤谚,不是則拋出異常
        assertMainThread("observe");
        // 判斷當(dāng)前的生命周期持有者是銷毀狀態(tài)棺蛛,則返回
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        // 創(chuàng)建LifecycleBoundObserver對(duì)象
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        // 判斷傳入的Map中是否已經(jīng)存在observer,如果存在則返回對(duì)象巩步,否則添加并返回空
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        // 如果已經(jīng)存在于map中旁赊,并且owner不同,則拋出異常
        if (existing != null && !existing.isAttachedTo(owner)) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        // 如果存在于map中椅野,則返回
        if (existing != null) {
            return;
        }
        // 如果existing為空终畅,map中不存在,則追加竟闪,從而實(shí)現(xiàn)對(duì)LifecycleOwner生命周期的感知
        owner.getLifecycle().addObserver(wrapper);
    }

    // 永久觀察离福,不在乎生命周期,只要數(shù)據(jù)發(fā)生變化炼蛤,就會(huì)通知Observer
    @MainThread
    public void observeForever(@NonNull Observer<? super T> observer) {
        // 判斷是否是主線程妖爷,不是則拋出異常
        assertMainThread("observeForever");
        // 創(chuàng)建AlwaysActiveObserver對(duì)象
        AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
        // 判斷傳入的Map中是否已經(jīng)存在observer,如果存在則返回對(duì)象理朋,否則添加并返回空
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        // 判斷map中存在Observer的類型絮识,如果類型是LifecycleBoundObserver,不是AlwaysActiveObserver嗽上,則拋出異常
        if (existing instanceof LiveData.LifecycleBoundObserver) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        // 如果map中存在則返回
        if (existing != null) {
            return;
        }
        // 直接分發(fā)數(shù)據(jù)
        wrapper.activeStateChanged(true);
    }

    // 移除現(xiàn)有的Observer
    @MainThread
    public void removeObserver(@NonNull final Observer<? super T> observer) {
        // 判斷是否是主線程
        assertMainThread("removeObserver");
        // 移除observer對(duì)象
        ObserverWrapper removed = mObservers.remove(observer);
        // 如果map中不存在則返回
        if (removed == null) {
            return;
        }
        // 通知生命周期持有者移除
        removed.detachObserver();
        // 不在分發(fā)數(shù)據(jù)
        removed.activeStateChanged(false);
    }

    // 移除指定生命周期持有者對(duì)應(yīng)的Observer
    @SuppressWarnings("WeakerAccess")
    @MainThread
    public void removeObservers(@NonNull final LifecycleOwner owner) {
        // 判斷是否是主線程
        assertMainThread("removeObservers");
        // 遍歷
        for (Map.Entry<Observer<? super T>, ObserverWrapper> entry : mObservers) {
            // 判斷是否owner一致
            if (entry.getValue().isAttachedTo(owner)) {
                // 移除
                removeObserver(entry.getKey());
            }
        }
    }

    /**
     * 子線程處理次舌,最終還是通過setValue函數(shù)使用主線程進(jìn)行分發(fā)數(shù)據(jù)
     * 
     * liveData.postValue("a");
     * liveData.setValue("b");
     * "b"會(huì)被setValue函數(shù)首先設(shè)置,隨后會(huì)在主線程被"a"覆蓋
     *
     * 如果在主線程執(zhí)行post之前兽愤,多次調(diào)用該函數(shù)彼念,那么只有最后一個(gè)值會(huì)被分發(fā)
     */
    protected void postValue(T value) {
        // 創(chuàng)建標(biāo)識(shí)
        boolean postTask;
        // 同步處理
        synchronized (mDataLock) {
            // mPendingData是否是默認(rèn)值
            postTask = mPendingData == NOT_SET;
            // 將mPendingData設(shè)置為傳入的value
            mPendingData = value;
        }
        // 如果mPendingData不是默認(rèn)值,則返回
        if (!postTask) {
            return;
        }
        // 主線程執(zhí)行mPostValueRunnable
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }

    /**
     * 設(shè)置數(shù)據(jù)浅萧,并且直接分發(fā)
     * 必須主線程調(diào)用
     */
    @MainThread
    protected void setValue(T value) {
        // 判斷是否在主線程
        assertMainThread("setValue");
        // 當(dāng)前持有數(shù)據(jù)版本高號(hào)加1
        mVersion++;
        // 實(shí)際數(shù)據(jù)設(shè)置為傳遞的參數(shù)
        mData = value;
        // 分發(fā)數(shù)據(jù)逐沙,并且參數(shù)傳遞為null,通知所有Observer
        dispatchingValue(null);
    }

    /**
     * 獲取當(dāng)前數(shù)據(jù).
     * 如果在子線程調(diào)用洼畅,有可能獲取的并不是最新的數(shù)據(jù)
     */
    @SuppressWarnings("unchecked")
    @Nullable
    public T getValue() {
        // 創(chuàng)建臨時(shí)變量酱吝,用于返回
        Object data = mData;
        // 當(dāng)數(shù)據(jù)不是默認(rèn)值的情況返回,否則返回空
        if (data != NOT_SET) {
            return (T) data;
        }
        return null;
    }

    // 獲取當(dāng)前數(shù)據(jù)版本
    int getVersion() {
        return mVersion;
    }

    /**
     * 當(dāng)觀察者數(shù)量從0變?yōu)?時(shí)調(diào)用.
     */
    protected void onActive() {

    }

    /**
     * 當(dāng)觀察者數(shù)量從1變?yōu)?時(shí)調(diào)用.
     * 并不意味這當(dāng)前沒有Observer了土思,只是觀察者可能不處于STARTED或者RESUMED狀態(tài),例如Activity在后臺(tái)
     * 可以使用hasObservers檢查當(dāng)前是否還有observer
     */
    protected void onInactive() {
        
    }

    /**
     * 判斷當(dāng)前是否還有Observer
     */
    @SuppressWarnings("WeakerAccess")
    public boolean hasObservers() {
        return mObservers.size() > 0;
    }

    /**
     * 判斷當(dāng)前是否還有處于Active狀態(tài)的Observer
     */
    @SuppressWarnings("WeakerAccess")
    public boolean hasActiveObservers() {
        return mActiveCount > 0;
    }

    // 更新Active狀態(tài)Observer的數(shù)量
    @MainThread
    void changeActiveCounter(int change) {
        // 將之前的數(shù)量保存到局部變量中
        int previousActiveCount = mActiveCount;
        // 當(dāng)前數(shù)量追加
        mActiveCount += change;
        // 當(dāng)前是否處于Active狀態(tài)务热,是Active狀態(tài)則返回
        if (mChangingActiveState) {
            return;
        }
        // 否則設(shè)置為true
        mChangingActiveState = true;
        try {
            // 判斷新舊數(shù)量是否一致
            while (previousActiveCount != mActiveCount) {
                // 之前沒有忆嗜,現(xiàn)在有了
                boolean needToCallActive = previousActiveCount == 0 && mActiveCount > 0;
                // 之前有,現(xiàn)在沒有了
                boolean needToCallInactive = previousActiveCount > 0 && mActiveCount == 0;
                // 局部變量和當(dāng)前保持一致了
                previousActiveCount = mActiveCount;
                if (needToCallActive) {
                    // 代表增加了
                    onActive();
                } else if (needToCallInactive) {
                    // 代表清空了
                    onInactive();
                }
            }
        } finally {
            // 將狀態(tài)設(shè)置為false
            mChangingActiveState = false;
        }
    }

    // 將LifecycleObserver和ObserverWrapper進(jìn)行關(guān)聯(lián)崎岂,當(dāng)生命周期發(fā)生改變捆毫,通知ObserverWrapper進(jìn)行更新
    class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
        
        // 生命周期持有者對(duì)象
        @NonNull
        final LifecycleOwner mOwner;

        // 構(gòu)造函數(shù)
        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
            super(observer);
            // 生命周期持有者賦值
            mOwner = owner;
        }

        // 判斷是否處于Active狀態(tài)
        // DESTROYED,
        // INITIALIZED,
        // CREATED,
        // STARTED,
        // RESUMED;
        // STARTED和RESUMED算是Active
        @Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }

        // 接收生命周期變化的回調(diào)
        @Override
        public void onStateChanged(@NonNull LifecycleOwner source,
                @NonNull Lifecycle.Event event) {
            // 獲取當(dāng)前生命周期的狀態(tài)
            Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
            if (currentState == DESTROYED) {
                // 如果是destoryed則移除觀察者,并返回
                removeObserver(mObserver);
                return;
            }
            // 定義局部變量
            Lifecycle.State prevState = null;
            while (prevState != currentState) {
                // 記錄當(dāng)前狀態(tài)
                prevState = currentState;
                // 更新狀態(tài)
                activeStateChanged(shouldBeActive());
                // 記錄當(dāng)前最新狀態(tài)
                currentState = mOwner.getLifecycle().getCurrentState();
            }
        }

        // 用于判斷是否是同一生命周期持有者
        @Override
        boolean isAttachedTo(LifecycleOwner owner) {
            return mOwner == owner;
        }

        // 移除Observer
        @Override
        void detachObserver() {
            mOwner.getLifecycle().removeObserver(this);
        }
    }

    // 抽象類ObserWrapper冲甘,用于LifecycleBoundObserver和AlwaysActiveObserver
    private abstract class ObserverWrapper {
        // 觀察者對(duì)象
        final Observer<? super T> mObserver;
        // 狀態(tài)
        boolean mActive;
        // 版本號(hào)
        int mLastVersion = START_VERSION;

        // 構(gòu)造函數(shù)
        ObserverWrapper(Observer<? super T> observer) {
            mObserver = observer;
        }

        // 抽象函數(shù)绩卤,判斷生命周期持有者當(dāng)前狀態(tài),給到LifecycleBoundObserver和AlwaysActiveObserver
        abstract boolean shouldBeActive();

        // LifecycleBoundObserver用于判斷生命周期持有者
        boolean isAttachedTo(LifecycleOwner owner) {
            return false;
        }

        // LifecycleBoundObserver用于移除Observer
        void detachObserver() {
        }

        // 狀態(tài)改變
        void activeStateChanged(boolean newActive) {
            // 如果狀態(tài)一致則返回
            if (newActive == mActive) {
                return;
            }
            // 立即設(shè)置活動(dòng)狀態(tài)江醇,這樣我們就不會(huì)向非活動(dòng)所有者發(fā)送任何內(nèi)容
            mActive = newActive;
            changeActiveCounter(mActive ? 1 : -1);
            if (mActive) {
                // 活動(dòng)狀態(tài)濒憋,分發(fā)數(shù)據(jù)
                dispatchingValue(this);
            }
        }
    }

    // 無視生命周期的觀察者
    private class AlwaysActiveObserver extends ObserverWrapper {

        // 構(gòu)造函數(shù)
        AlwaysActiveObserver(Observer<? super T> observer) {
            super(observer);
        }

        // 無視生命周期,直接返回true
        @Override
        boolean shouldBeActive() {
            return true;
        }
    }

    // 線程判斷
    static void assertMainThread(String methodName) {
        if (!ArchTaskExecutor.getInstance().isMainThread()) {
            throw new IllegalStateException("Cannot invoke " + methodName + " on a background"
                    + " thread");
        }
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末陶夜,一起剝皮案震驚了整個(gè)濱河市凛驮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌条辟,老刑警劉巖黔夭,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異羽嫡,居然都是意外死亡本姥,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門杭棵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來婚惫,“玉大人,你說我怎么就攤上這事魂爪∠认希” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵甫窟,是天一觀的道長。 經(jīng)常有香客問我蛙婴,道長粗井,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任街图,我火速辦了婚禮浇衬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘餐济。我一直安慰自己耘擂,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布絮姆。 她就那樣靜靜地躺著醉冤,像睡著了一般秩霍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蚁阳,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天铃绒,我揣著相機(jī)與錄音,去河邊找鬼螺捐。 笑死颠悬,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的定血。 我是一名探鬼主播赔癌,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼澜沟!你這毒婦竟也來了灾票?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤倔喂,失蹤者是張志新(化名)和其女友劉穎铝条,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體席噩,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡班缰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了悼枢。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片埠忘。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖馒索,靈堂內(nèi)的尸體忽然破棺而出莹妒,到底是詐尸還是另有隱情,我是刑警寧澤绰上,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布旨怠,位于F島的核電站,受9級(jí)特大地震影響蜈块,放射性物質(zhì)發(fā)生泄漏鉴腻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一百揭、第九天 我趴在偏房一處隱蔽的房頂上張望爽哎。 院中可真熱鬧,春花似錦器一、人聲如沸课锌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽渺贤。三九已至雏胃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間癣亚,已是汗流浹背丑掺。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留述雾,地道東北人街州。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像玻孟,于是被迫代替她去往敵國和親唆缴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 上一篇文章解析了一下Lifecycle的源碼剖析Lifecycle源碼[https://www.jianshu.c...
    Whanter閱讀 829評(píng)論 0 7
  • 首先LiveData是一個(gè)抽象類黍翎,是不能直接new一個(gè)出來的面徽,通常是使用MutableLiveData創(chuàng)建一個(gè)li...
    vavaj閱讀 412評(píng)論 0 0
  • ??距離上一篇文章差不多有一個(gè)月,感覺進(jìn)度有點(diǎn)慢匣掸。唉趟紊,在這一個(gè)月里面,自己有點(diǎn)頹廢芭鲈汀霎匈!這篇文章居然拖了這么久。廢話...
    瓊珶和予閱讀 672評(píng)論 0 5
  • LiveData是一個(gè)數(shù)據(jù)持有者送爸,其本身實(shí)現(xiàn)了觀察者模式铛嘱,支持?jǐn)?shù)據(jù)監(jiān)控(被觀察),并且可以感知組件的生命周期袭厂。觀察...
    打不死的小強(qiáng)qz閱讀 4,265評(píng)論 5 7
  • 在之前學(xué)習(xí)MVVM的搭建的時(shí)候涉及到了LiveData這個(gè)可被觀察的數(shù)據(jù)持有類墨吓,在ViewModel中使用Live...
    Rannver閱讀 923評(píng)論 0 0