Jetpack入门(二)LifeData介绍及原理浅析

前言

LiveData是一种具有生命周期感知能力的可观察数据持有类,LiveData可以保证屏幕的显示内容和数据一直保持同步,具有如下特点:
1.LiveData可以感知到UI界面的状态,如果activity不在屏幕上显示,LiveData不会触发没必要的界面更新,如果activity已经销毁,会自动清空与observer的连接,意外调用就不会发生。

2.LiveData是一个lifecycleOwner,也可以直接感知activity或fragment的声明周期。

原理分析

//this表示了实现lifecycleOwner接口,比如AppcompatActivity
 model.getCurrentName().observe(this,observer);

observe作为入口,接着去看observe里面做了啥事:

 public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        //看看这个owner的状态是否是destroy,
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
      ······
      //前面说到,LiveData是一个lifecycleOwner,这里的流程和第一篇Lifecycle一样了。
       owner.getLifecycle().addObserver(wrapper);
}

使用LifecycleBoundObserver 将观察者和被观察者包装在一起,绑定wrapper作为观察者。绑定完成后,使用setValue和postValue通知观察者

 protected void setValue(T value) {
        assertMainThread("setValue");
        //这里的mVersion就是保证只处理最新的事件。
        mVersion++;
        mData = value;
        //主要逻辑在这
        dispatchingValue(null);
    }

接着去看看 dispatchingValue(null)做了啥事

  void dispatchingValue(@Nullable ObserverWrapper initiator) {
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
          //参数不为null 注释①
            if (initiator != null) {
                //具体实现 注释②
                considerNotify(initiator);
                initiator = null;
            } else {//参数不为null
                for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                  //具体实现
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }

注释①:参数为null时,将通过迭代器去通知所有观察者,反之,则通知传入的观察者。
注释②:通知观察者后,要求观察者做出相应的处理,处理逻辑就在considerNotify(initiator);中

接着去看看considerNotify(initiator)做了啥事:

private void considerNotify(ObserverWrapper observer) {
       //系统判断 注释③
        if (!observer.mActive) {
            return;
        }
       //系统判断
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        //注释④
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;//通过就更新这个mLastVersion
        observer.mObserver.onChanged((T) mData);
    }

注释③:判断activity是否为显示状态,
注释④:对于liveData,初始值是-1,调用setValue时会加一,调用一次observe(),生成一个ObserverWrapper,对于每个ObserverWrapper,其初始version也为-1。所以if走不进去,故会走到订阅者的onChange()方法。

还有一种通知方式就是在子线程时,使用postValue,原理是切换到主线程再使用setValue();

总结

LifeData可以看作一种数据持有者,它可以感知activty或fragment的生命周期。再调用observe
()时,也会先判断activity的状态是否被销毁。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。