免费爱碰视频在线观看,九九精品国产屋,欧美亚洲尤物久久精品,1024在线观看视频亚洲

      Android Jetpack系列(四):LiveData (原理篇)

      Android Jetpack系列(四):LiveData (原理篇)

      前言

      在上一篇文章中我們學(xué)習(xí)了LiveData的基本用法, 我們知道LiveData是一個可觀察的數(shù)據(jù)持有者,他是具有組件生命周期感知的,那么它是如何觀察組件生命周期變化的呢?

      LiveData和RxJava的不同的是,LiveData并不是通知所有觀察者,它只會通知處于Active狀態(tài)的觀察者; 如果一個觀察者處于DESTROYED狀態(tài),它將不會收到通知,這一點又是如何做到的?還有另外一點,Transformations的map方法其內(nèi)部進(jìn)行了什么操作?等等問題,會在這篇文章中給大家進(jìn)行講解

      1.LiveData如何觀察組件生命周期變化

      通過調(diào)用LiveData的observe方法來注冊觀察者,LiveData的observe方法如下所示。

      @MainThread public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) { assertMainThread(“observe”); //如果被觀察者的當(dāng)前的狀態(tài)是DESTROYED,就return if (owner.getLifecycle().getCurrentState() == DESTROYED) {//1 return; } LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);//2 ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);//3 if (existing != null && !existing.isAttachedTo(owner)) { throw new IllegalArgumentException(“Cannot add the same observer” + ” with different lifecycles”); } if (existing != null) { return; } owner.getLifecycle().addObserver(wrapper);//4 }

      注釋1處的owner實際上就是注冊時傳進(jìn)來來組件; 比如Activity,獲取組件當(dāng)前的狀態(tài),如果狀態(tài)為DESTROYED,那么直接return,這說明DESTROYED狀態(tài)的組件是不允許注冊的。

      注釋2處新建了一個LifecycleBoundObserver包裝類,將owner和observer傳了進(jìn)去

      注釋3處將observer和LifecycleBoundObserver存儲到SafeIterableMapmObservers中; putIfAbsent方法和put方法有區(qū)別,如果傳入key對應(yīng)的value已經(jīng)存在,就返回存在的value,不進(jìn)行替換。如果不存在,就添加key和value,返回null。 如果等于null,在注釋4處會將LifecycleBoundObserver添加到Lifecycle中完成注冊,這樣當(dāng)我們調(diào)用LiveData的observe方法時,實際上是LiveData內(nèi)部完成了Lifecycle的觀察者的添加,這樣LiveData自然也就有了觀察組件生命周期變化的能力。

      2.LiveData的observe方法回調(diào)

      LifecycleBoundObservers是LiveData的內(nèi)部類,代碼如下所示

      class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver { @NonNull final LifecycleOwner mOwner; LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer 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) { removeObserver(mObserver);//1 return; } activeStateChanged(shouldBeActive());//2 } @Override boolean isAttachedTo(LifecycleOwner owner) { return mOwner == owner; } @Override void detachObserver() { mOwner.getLifecycle().removeObserver(this); } }

      LifecycleBoundObserver繼承了ObserverWrapper類; 重寫了shouldBeActive方法,用于判斷當(dāng)前傳入的組件的狀態(tài)是否是Active的,Active狀態(tài)包括STARTED和RESUMED狀態(tài)

      LifecycleBoundObserver實現(xiàn)了GenericLifecycleObserver接口; 當(dāng)組件狀態(tài)發(fā)生變化時,會調(diào)用onStateChanged方法,當(dāng)組件處于DESTROYED狀態(tài)時,會調(diào)用注釋1處的removeObserver方法,來移除observer。 這樣在文章開頭的疑問就解決了,為什么一個觀察者(組件)處于DESTROYED狀態(tài)時,它將不會收到通知

      接著會調(diào)用注釋2處的activeStateChange方法,代碼如下所示

      private abstract class ObserverWrapper { final Observer mObserver; boolean mActive; int mLastVersion = START_VERSION; ObserverWrapper(Observer observer) { mObserver = observer; } abstract boolean shouldBeActive(); boolean isAttachedTo(LifecycleOwner owner) { return false; } void detachObserver() { } void activeStateChanged(boolean newActive) { if (newActive == mActive) { return; } 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);//1 } } }

      activeStateChanged方法定義在抽象類ObserverWrapper中; 它是Observer的包裝類,activeStateChanged方法會根據(jù)Active狀態(tài)和處于Active狀態(tài)的組件的數(shù)量,來對onActive方法和onInactive方法回調(diào),這兩個方法用于拓展LiveData對象。注釋1處,如果是Active狀態(tài),會調(diào)用dispatchingValue方法,并將自身傳進(jìn)去

      private void dispatchingValue(@Nullable ObserverWrapper initiator) { //正在處于分發(fā)狀態(tài)中 if (mDispatchingValue) { //分發(fā)無效 mDispatchInvalidated = true;//1 return; } mDispatchingValue = true; do { //分發(fā)有效 mDispatchInvalidated = false; if (initiator != null) { considerNotify(initiator); initiator = null; } else { for (Iterator<Map.Entry> iterator = mObservers.iteratorWithAdditions(); iterator.hasNext(); ) { considerNotify(iterator.next().getValue()); if (mDispatchInvalidated) { break; } } } } while (mDispatchInvalidated); //標(biāo)記不處于分發(fā)狀態(tài) mDispatchingValue = false; }

      mDispatchingValue用于標(biāo)記當(dāng)前是否處于分發(fā)狀態(tài)中; 如果處于該狀態(tài),則在注釋1處標(biāo)記當(dāng)前分發(fā)無效,直接return;一路調(diào)用過來,ObserverWrapper是不為null的,ObserverWrapper為null的情況第3小節(jié)會講到,無論是那種情況,都會調(diào)用considerNotify方法,代碼如下所示

      private void considerNotify(ObserverWrapper observer) { if (!observer.mActive) {//1 return; } if (!observer.shouldBeActive()) { observer.activeStateChanged(false);//2 return; } if (observer.mLastVersion >= mVersion) { return; } observer.mLastVersion = mVersion; //noinspection unchecked observer.mObserver.onChanged((T) mData);//3 }

      considerNotify方法中做了多次的判斷; 注釋1處,如果ObserverWrapper的mActive值不為true,就直接return;注釋2處,如果當(dāng)前observer對應(yīng)組件的狀態(tài)不是Active,就會再次調(diào)用activeStateChanged方法,并傳入false,其方法內(nèi)部會再次判斷是否執(zhí)行onActive方法和onInactive方法回調(diào)

      如果判斷條件都滿足會調(diào)用Observer的onChanged方法,這個方法正是使用LiveData的observe方法的回調(diào)

      3.postValue/setValue方法分析

      當(dāng)調(diào)用MutableLiveData的observe方法后,還需要通過postValue/setValue方法來更新數(shù)據(jù)

      … private final Runnable mPostValueRunnable = new Runnable() { @Override public void run() { Object newValue; synchronized (mDataLock) { newValue = mPendingData; mPendingData = NOT_SET; } //noinspection unchecked setValue((T) newValue);//1 } }; … protected void postValue(T value) { boolean postTask; synchronized (mDataLock) { postTask = mPendingData == NOT_SET; mPendingData = value; } if (!postTask) { return; } ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);//2 } @MainThread //3 protected void setValue(T value) { assertMainThread(“setValue”); mVersion++; mData = value; dispatchingValue(null); }

      postValue/setValue方法都定義在LiveData中; 根據(jù)注釋1和注釋2處,可以發(fā)現(xiàn)postValue方法實際上就是將setValue方法切換到主線程調(diào)用。注釋3處說明setValue方法是運行在主線程中的,其內(nèi)部調(diào)用了dispatchingValue方法,這個方法在第2小節(jié)介紹過,也就是dispatchingValue方法的參數(shù)ObserverWrapper為null的情況

      從這里我們可以知道,無論是LiveData的observe方法還是LiveData的postValue/setValue方法都會調(diào)用dispatchingValue方法

      4.Transformations.map方法分析

      除了以上講的常用的方法之外,還可能會使用到Transformations.map和Transformations.switchMap方法,這里以Transformations.map為例; 這個方法用來在LiveData對象分發(fā)給觀察者之前對其中存儲的值進(jìn)行更改, 代碼如下所示

      @MainThread public static LiveData map( @NonNull LiveData source, @NonNull final Function mapFunction) { final MediatorLiveData result = new MediatorLiveData();//1 result.addSource(source, new Observer() { @Override public void onChanged(@Nullable X x) { result.setValue(mapFunction.apply(x)); } }); return result; }

      Transformations.map方法運行在主線程,注釋1處創(chuàng)建了MediatorLiveData,緊接著調(diào)用了它的addSource方法:

      */ @MainThread public void addSource(@NonNull LiveData source, @NonNull Observer onChanged) { Source e = new Source(source, onChanged);//1 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();//2 } }

      注釋1處將傳進(jìn)來的LiveData和onChanged封裝到Source類中,注釋2處調(diào)用了Source的plug方法:

      private static class Source implements Observer { final LiveData mLiveData; final Observer mObserver; int mVersion = START_VERSION; Source(LiveData liveData, final Observer observer) { mLiveData = liveData; mObserver = observer; } void plug() { mLiveData.observeForever(this);//1 } void unplug() { mLiveData.removeObserver(this); } @Override public void onChanged(@Nullable V v) { if (mVersion != mLiveData.getVersion()) { mVersion = mLiveData.getVersion(); mObserver.onChanged(v);//2 } } }

      注釋2處可以看到,Transformations.map方法傳入的Observer的回調(diào)在這里進(jìn)行處理; 注釋1處,Source的plug方法會調(diào)用LiveData的observeForever方法,這個和第2小節(jié)所講的內(nèi)容有什么區(qū)別呢?我們再往下看

      @MainThread public void observeForever(@NonNull Observer observer) { assertMainThread(“observeForever”); AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);//1 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); }

      注釋1處用AlwaysActiveObserver來對Observer進(jìn)行包裝,緊接著調(diào)用AlwaysActiveObserver的activeStateChanged方法; 其內(nèi)部實際調(diào)用的是ObserverWrapper的activeStateChanged方法,這個在第二小節(jié)已經(jīng)做了分析,就不再贅述了。來看AlwaysActiveObserver類是如何定義的

      private class AlwaysActiveObserver extends ObserverWrapper { AlwaysActiveObserver(Observer observer) { super(observer); } @Override boolean shouldBeActive() { return true; } }

      AlwaysActiveObserver是LiveData的內(nèi)部類; 它繼承自O(shè)bserverWrapper,AlwaysActiveObserver是LiveData的內(nèi)部類和ObserverWrapper的區(qū)別就是,它是永遠(yuǎn)處于Active狀態(tài)的

      5.LiveData關(guān)聯(lián)類

      其中MutableLiveData繼承自LiveData,LifecycleOwner和Observer和LiveData有關(guān)聯(lián)的關(guān)系,ObserverWrapper是Observer的包裝類,因此它們有著關(guān)聯(lián)的關(guān)系

      有需要文中完整代碼的同學(xué): 《現(xiàn)在私信發(fā)送 “底層源碼” 即可免費獲取》

      現(xiàn)在私信發(fā)送 “筆記” 還可以獲取《更多 Android 源碼解析+學(xué)習(xí)大綱+核心筆記》

      最后我想說:

      對于程序員來說,要學(xué)習(xí)的知識內(nèi)容、技術(shù)有太多太多,要想不被環(huán)境淘汰就只有不斷提升自己,從來都是我們?nèi)ミm應(yīng)環(huán)境,而不是環(huán)境來適應(yīng)我們

      技術(shù)是無止境的,你需要對自己提交的每一行代碼、使用的每一個工具負(fù)責(zé),不斷挖掘其底層原理,才能使自己的技術(shù)升華到更高的層面

      Android 架構(gòu)師之路還很漫長,與君共勉

      鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
      用戶投稿
      上一篇 2022年7月31日 10:56
      下一篇 2022年7月31日 10:56

      相關(guān)推薦

      • 分享4條發(fā)微商朋友圈的方法(微商朋友圈應(yīng)該怎么發(fā))

        對于微商朋友來說,朋友圈的重要性不言而喻了。 那么微商的朋友圈到底該怎么發(fā)呢? 為什么同樣是經(jīng)營一個朋友圈,有的微商看起來逼格滿滿,實際效果也不錯;而有的卻動都不動就被屏蔽甚至拉黑…

        2022年11月27日
      • 《寶可夢朱紫》夢特性怎么獲得?隱藏特性獲取方法推薦

        寶可夢朱紫里有很多寶可夢都是擁有夢特性會變強的寶可夢,很多玩家不知道夢特性怎么獲得,下面就給大家?guī)韺毧蓧糁熳想[藏特性獲取方法推薦,感興趣的小伙伴一起來看看吧,希望能幫助到大家。 …

        2022年11月25日
      • 《寶可夢朱紫》奇魯莉安怎么進(jìn)化?奇魯莉安進(jìn)化方法分享

        寶可夢朱紫中的奇魯莉安要怎么進(jìn)化呢?很多玩家都不知道,下面就給大家?guī)韺毧蓧糁熳掀骠斃虬策M(jìn)化方法分享,感興趣的小伙伴一起來看看吧,希望能幫助到大家。 奇魯莉安進(jìn)化方法分享 奇魯莉安…

        2022年11月25日
      • 鬧劇落下帷幕,曼聯(lián)官宣 C 羅離隊

        1、鬧劇落下帷幕,曼聯(lián)官宣 C 羅離隊 在經(jīng)歷過半個賽季的激烈鬧劇、C 羅私自接受采訪炮轟曼聯(lián)之后,俱樂部終于做出了相對應(yīng)的措施:正式官宣 C 羅離隊。 在曼聯(lián)俱樂部發(fā)布的聲明中寫…

        2022年11月24日
      • iqoo11什么時候上市 iqoo11發(fā)布時間最新消息

        iqoo11什么時候發(fā)布?隨著新一代旗艦芯片的發(fā)布,各家手機(jī)廠商也是公布了自己的旗艦機(jī),那么iqoo11什么時候發(fā)布呢?下面就讓小編為大家介紹一下,一起來看看吧。 iqoo11什么…

        2022年11月24日
      • 曝小米13系列已量產(chǎn):起步價格或定在4500元左右

        高通目前已經(jīng)發(fā)布第二代驍龍8芯片,首批機(jī)型已經(jīng)蓄勢待發(fā),小米此前也已經(jīng)宣布新旗艦要率先搭載。 據(jù)澎湃報道,小米13系列已經(jīng)正式量產(chǎn),全系均搭載4nm芯片,不出意外是標(biāo)配第二代驍龍8…

        2022年11月24日
      • 王者榮耀高幀率模式支持機(jī)型列表最新 新增機(jī)型名單

        11月24日上午8:30-9:30,《王者榮耀》將進(jìn)行全服不停機(jī)更新。本次更新大小安卓約33MB,iOS約44MB。 為了讓玩家們能享受更平滑,更精美的王者榮耀操作畫面體驗,在設(shè)置…

        2022年11月24日
      • 《寶可夢朱紫》暴飛龍怎么抓?暴飛龍獲得方法

        寶可夢朱紫暴飛龍位置在哪?在游戲中,很多玩家還不清楚暴飛龍具體要怎么樣獲得,其實獲得方法很簡單,暴飛龍直接是沒得抓的,需要玩家從寶貝龍進(jìn)化得到,下面一起來看一下寶可夢朱紫暴飛龍獲得…

        2022年11月23日
      • 《寶可夢朱紫》布土撥怎么進(jìn)化?布土撥進(jìn)化方法介紹

        寶可夢朱紫中,不同的寶可夢有不同的進(jìn)化方法,其中布土撥的進(jìn)化方法是比較特殊的。很多玩家不知道寶可夢朱紫布土撥怎么進(jìn)化,下面就帶來寶可夢朱紫布土撥進(jìn)化方法介紹,一起來看看吧,希望能幫…

        2022年11月23日
      • 《寶可夢朱紫》薄荷怎么獲得?薄荷獲得方法

        寶可夢朱紫中薄荷有改變寶可夢的屬性或性格等效果,很多玩家想知道寶可夢朱紫薄荷怎么獲得,下面就帶來寶可夢朱紫薄荷獲得方法,感興趣的小伙伴一起來看看吧,希望能幫助到大家。 薄荷獲得方法…

        2022年11月23日

      聯(lián)系我們

      聯(lián)系郵箱:admin#wlmqw.com
      工作時間:周一至周五,10:30-18:30,節(jié)假日休息