Android liveData源碼解析

一.LiveData是什么?
LiveData是一種可感知生命周期的組件,在Activity\Fragment\Service等組件都處于活躍可見的狀態(tài)的時(shí)候,才去更新app的頁面的
優(yōu)點(diǎn)不會造成內(nèi)存泄漏等

二.LiveData使用
添加依賴

api "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
api "androidx.lifecycle:lifecycle-extensions:2.2.0"

為了方便我就寫一個(gè)單例

object MyLiveData {
   val liveData by lazy { MutableLiveData<String>() }
}

setValue是主線程中使用,postValue異步線程使用

MyLiveData.liveData.value="1233"

訂閱消息

MyLiveData.liveData.observe(this,{
           Toast.makeText(this,it,Toast.LENGTH_LONG).show()
       })

三.源碼分析
1.LiveData,observe

@MainThread
  public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
      assertMainThread("observe");//檢查線程
//這行代碼可以先去了解下Lifecycle的源碼分析,這段代碼的意思就是拿到當(dāng)前的狀態(tài)和DESTROYED做比較,如果相等的話return 就不會觸發(fā)onChanged方法
      if (owner.getLifecycle().getCurrentState() == DESTROYED) {
          // ignore
          return;
      }
  //包裝類
      LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
      ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
      if (existing != null && !existing.isAttachedTo(owner)) {
          throw new IllegalArgumentException("Cannot add the same observer"
                  + " with different lifecycles");
      }
      if (existing != null) {
          return;
      }
    //可以去參考lifecycle源碼分析,目的就是觀察生命周期
      owner.getLifecycle().addObserver(wrapper);
  } 

我們看到這個(gè)方法只傳了兩個(gè)參數(shù),第一個(gè)參數(shù)是owner,第二個(gè)參數(shù)是observer.首先第一個(gè)參數(shù)為什么傳this就可以了?因?yàn)?br> ComponentActivity實(shí)現(xiàn)LifecycleOwner接口,具體的可以去看Lifecycle的源碼分析,第二個(gè)參數(shù)也就是一個(gè)接口
2.LiveData.LifecycleBoundObserver

 class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
       @NonNull
       final LifecycleOwner mOwner;
 
       LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
           super(observer);
           mOwner = owner;
       }

       @Override      //只有當(dāng)頁面可見的時(shí)候返回為true
       boolean shouldBeActive() {
           return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
       }

       @Override  //執(zhí)行每個(gè)生命周期函數(shù)都會回調(diào)這個(gè)函數(shù)
       public void onStateChanged(@NonNull LifecycleOwner source,
               @NonNull Lifecycle.Event event) {
           if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {  //如果頁面銷毀了就移除觀察者
               removeObserver(mObserver);
               return;
           }
           activeStateChanged(shouldBeActive());
       }

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

       @Override
       void detachObserver() {
           mOwner.getLifecycle().removeObserver(this);
       }
   }

LifecycleBoundObserver把我們傳進(jìn)來的LifecycleOwner和觀察者Observer做了一個(gè)保存.也就是它是對LifecycleOwner和Observer做了一次封裝,onStateChanged執(zhí)行每個(gè)生命周期函數(shù)都會回調(diào)這個(gè)函數(shù)的,why?為什么呢! 這里大致總結(jié)一下
在ComponentActivity里面初始化了LifecycleRegistry并且創(chuàng)建了一個(gè)透明的Fragment,在Fragment里面的每個(gè)生命周期函數(shù)里面都會調(diào)用相應(yīng)的dispatch方法,例如(Lifecycle.Event.ON_START),最終分發(fā)到LifecycleEventObserver.onStateChanged方法.
LifecycleBoundObserver 這個(gè)實(shí)現(xiàn)了LifecycleEventObserver接口,所以會分發(fā)到到這個(gè)方法

3.LifecycleBoundObserver.onStateChanged
activeStateChanged(shouldBeActive()) shouldBeActive只有當(dāng)狀態(tài)是STARTED和RESUMED的時(shí)候才會是true

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) { //頁面可見的時(shí)候
               onActive();   //這是一個(gè)空函數(shù)一般用不到
           }
           if (LiveData.this.mActiveCount == 0 && !mActive) { //頁面不可見的時(shí)候
               onInactive();  //這是一個(gè)空函數(shù)一般用不到
           }
           if (mActive) { //如果頁面存活的調(diào)用這個(gè)方法
               dispatchingValue(this);
           }
       }

dispatchingValue(this),在LiveData.setValue方法中dispatchingValue傳入的是null

//不管是initiator 等不等于null  最后都會把觀察者包裝器initiator傳了considerNotify方法
void dispatchingValue(@Nullable ObserverWrapper initiator) {
       if (mDispatchingValue) { //默認(rèn)情況下是false
           mDispatchInvalidated = true;
           return;
       }
       mDispatchingValue = true;
       do {
           mDispatchInvalidated = false;
           if (initiator != null) {
               considerNotify(initiator);
               initiator = null;
           } else {
               //調(diào)用initiator=null的情況下是執(zhí)行下面的循環(huán) 遍歷過個(gè)觀察者
               for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                       mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                   considerNotify(iterator.next().getValue());
                   if (mDispatchInvalidated) {
                       break;
                   }
               }
           }
       } while (mDispatchInvalidated);
       mDispatchingValue = false;
   }

在dispatchingValue里面?zhèn)魅肓藅his,然后進(jìn)行循環(huán),這時(shí)候if (initiator != null) 滿足條件就會調(diào)用considerNotify方法

   private void considerNotify(ObserverWrapper observer) {
       if (!observer.mActive) { //如果不是存活狀態(tài)的話就return
           return;
       }
       if (!observer.shouldBeActive()) {
           observer.activeStateChanged(false);
           return;
       }
       if (observer.mLastVersion >= mVersion) {
           return;
       }
       observer.mLastVersion = mVersion;
       observer.mObserver.onChanged((T) mData);
   }

有沒有很奇怪為什么又來判斷一次 if (!observer.shouldBeActive()) 并且調(diào)用了 observer.activeStateChanged(false),這個(gè)目的就是為了進(jìn)一步確認(rèn)是否是可見狀態(tài),因?yàn)槟愕腶ctivity可能突然一下不可見了,例如你切換到后臺了這時(shí)候不可見了,這時(shí)候是需要調(diào)用這個(gè)方法進(jìn)行拿到頁面是否可見

if (observer.mLastVersion >= mVersion)這行代碼的意思決定著粘性事件的分發(fā).什么是粘性事件? 粘性事件就是:先liveData.value設(shè)置數(shù)據(jù),然后再去注冊liveData.observe 這個(gè)就加做粘性事件!,如果不需要粘性事件,可以通過反射來讓他們相等
observer.mLastVersion(觀察者)默認(rèn)是-1,而mVersion默認(rèn)情況下是0,當(dāng)你調(diào)用LiveData.value的set方法時(shí)候就會進(jìn)行++一次 .假如現(xiàn)在是先調(diào)用LiveData.setValue,mVersion++了一次.這時(shí)候是mVersion等于1,然后在注冊liveData.observe ,這時(shí)候observer.mLastVersion還沒有進(jìn)行賦值還是-1
,所以這時(shí)候 if (observer.mLastVersion >= mVersion) 不滿足條件,最后調(diào)用了observer.mObserver.onChanged方法,這個(gè)onChanged,就是我們在observe的時(shí)候傳入的第二個(gè)參數(shù),所以就能拿到數(shù)據(jù)了

總結(jié):
1.在observe(this,observer)方法創(chuàng)建一個(gè)LifecycleBoundObserver,這LifecycleBoundObserver繼承ObserverWrapper實(shí)現(xiàn)了LifecycleEventObserver接口,在LifecycleBoundObserver里面對LifecycleOwner和observer進(jìn)行了保存
2.當(dāng)activity生命周期發(fā)生變化的時(shí)候會執(zhí)行LifecycleBoundObserver.onStateChanged,那是因?yàn)镃omponentActivity里面初始化了LifecycleRegistry并且創(chuàng)建了一個(gè)透明的Fragment,在Fragment里面的就可以感應(yīng)activity每個(gè)生命周期函數(shù),并且里面都會調(diào)用相應(yīng)的dispatch方法,例如(Lifecycle.Event.ON_START),最終分發(fā)到LifecycleEventObserver.onStateChanged方法
3.如果發(fā)現(xiàn)mActive是tue的話才會observer.onChanged方法,只有當(dāng)onStart和onResume的時(shí)候mActive才會為tue

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

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

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