LiveData的使用和原理

一、LiveData的基本使用
//创建一个LiveData对象
private val livedata = MutableLiveData<String>();

//为LiveData设置监听
livedata.observe(this, Observer {
    Log.e("znh", "监听到livedata的数据了:${it}")
})

//设置LiveData的值
livedata.value = "测试数据"

上述代码中,当LiveData的value值改变时,就会触发observe方法中设置的监听。

二、LiveData的工作原理

MutableLiveData的observe方法里需要传递两个参数,第一个参数是LifecycleOwner的子类,实现了这个接口的子类就是一个被观察者,AppCompatActivity实现了LifecycleOwner接口成为了一个生命周期可被观察的被观察者,所以第一个参数可以设置为Activity自身。第二个参数是观察LiveData数据的观察者Observer。

在LiveData的observe方法中,会将LifecycleOwner和Observer两个参数关联起来封装到wrapper中去,然后将wrapper作为Lifecycle的一个观察者添加到观察者集合中,这样当Activity的生命周期发生改变时,wrapper就可以感知到(具体的感知过程可以查看《Lifecycle的基本使用和原理》),这样Livedata就可以根据wrapper感知到的生命周期状态去处理跟Activity的关系,并决定是否要向Observer发送Livedata的数据。

除了上面Activity的生命周期发生改变时,有可能会触发向Observer发送Livedata数据的一个事件外,当LiveData的setValue或者postValue被调用时也会触发这样一个事件(具体的过程是通过调用dispatchingValue方法来实现的)。

下面看下LiveData的observe方法源码:

@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
      assertMainThread("observe");

	  //注释1 判断owner的生命周期状态是不是被销毁了
      if (owner.getLifecycle().getCurrentState() == DESTROYED) {
          // ignore
          return;
      }

	  //注释2
      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;
      }

	  //注释3 为lifecycle添加观察者
      owner.getLifecycle().addObserver(wrapper);
 }

在注释2处将owner和observer封装到LifecycleBoundObserver中,然后在将wrapper添加到mObservers中,mObservers是以observer为key,wrapper为value的map集合,这样可以从集合中通过observer来找到封装它的LifecycleBoundObserver对象。

在注释3处将wrapper作为一个观察者添加到Lifecycle的观察者集合中,这样wrapper就具备了观察Lifecycle生命周期的能力。

LifecycleBoundObserver源码:

class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
        @NonNull
        final LifecycleOwner mOwner;

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

        @Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }

		//注释4
        @Override
        public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
        	//注释5
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                removeObserver(mObserver);
                return;
            }
            
            //注释6
            activeStateChanged(shouldBeActive());
        }

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

        @Override
        void detachObserver() {
        	//注释7
            mOwner.getLifecycle().removeObserver(this);
        }
}

从注释3处可以知道LifecycleBoundObserver类型的wrapper对象也是LifecycleObserver的子类,它作为lifecycle的一个观察者,当lifecycle回调生命周期方法的时候,会回调注释4处wrapper的onStateChanged方法。

在注释5处如果Lifecycle生命周期状态是DESTROYED那么就会将该wrapper从map(这里的map就是注释2处添加wrapper的mObservers)中移除掉并结束事件流,这里的移除操作会触发在注释7处的detachObserver方法调用,将wrapper从Lifecycle的观察者集合中移除掉,解除UI层对数据的监听,这样就解决了LiveData在UI层的内存泄漏问题。

如果生命周期没有结束,那么就会继续执行注释6处的activeStateChanged方法,在activeStateChanged中会调用dispatchingValue方法,在dispatchingValue方法中又会调用considerNotify方法处理事件流,considerNotify源码如下:

private void considerNotify(ObserverWrapper observer) {
       if (!observer.mActive) {
           return;
       }

       if (!observer.shouldBeActive()) {
           observer.activeStateChanged(false);
           return;
       }

	   //注释8
       if (observer.mLastVersion >= mVersion) {
           return;
       }
       observer.mLastVersion = mVersion;
       
       //注释9
       observer.mObserver.onChanged((T) mData);
}

在注释8处mVersion是LiveData中的一个变量,初始值为-1,每次LiveData进行postValue或者setValue时,mVersion都会进行++操作,mLastVersion是观察者ObserverWrapper中的一个变量,只有mLastVersion小于mVersion时才会进行数据分发并且会同步二者的值,否则就结束事件流,这样做可以防止数据的重复多次发送。

在注释9处会调用ObserverWrapper中封装的mObserver(这个就是在UI层通过LiveData的observe方法的第二个参数传递的观察者对象)观察者的onChanged方法,这样在UI层就能接收到数据了。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值