Android jetpack LiveData (二) 原理篇
Android jetpack LiveData二原理篇引言源码前置分析核心类源码第一步定义LiveData对象第二步观察LiveData数据第三步 设置LiveData数据到这里我们先总结下黏性数据的步骤小结引言上一篇我们学习了LifeCycle的简单使用Android jetpack LiveData一使用篇那在这一篇主要学习LiveData的原理。源码前置分析核心类LiveData抽象类定义了 LiveData 的基本行为和接口。MutableLiveDataLiveData 的子类提供了 setValue 和 postValue 方法用于更新数据。Observer观察者接口用于定义数据更新时的回调方法。LifecycleBoundObserver实现了 Observer 接口并且具有生命周期感知能力确保只在合适的生命周期状态下通知观察者。LiveData.java定义了基本的数据观察和设置方法。publicabstractclassLiveDataT{MainThreadpublicvoidobserve(NonNullLifecycleOwner owner,NonNullObserver?superTobserver){...}MainThreadpublicvoidobserveForever(NonNullObserver?superTobserver){...}protectedvoidpostValue(T value){...}MainThreadprotectedvoidsetValue(T value){...}protectedvoidonActive(){}protectedvoidonInactive(){}}MutableLiveData.javaLiveData的子类publicclassMutableLiveDataTextends LiveDataT{OverridepublicvoidpostValue(T value){super.postValue(value);}OverridepublicvoidsetValue(T value){super.setValue(value);}}源码我们按照使用的顺序来进行源码分析第一步定义LiveData对象publicMutableLiveData(){super();}在核心类里面了解到MutableLiveData是LiveData的子类所以我们去LiveData中看定义。在这里进行数据对象初始化。publicabstractclassLiveDataT{publicLiveData(T value){mDatavalue;mVersionSTART_VERSION1;}publicLiveData(){// 逻辑走这里mDataNOT_SET;mVersionSTART_VERSION;// -1 (初始为-1 哦后面会用到)}}第二步观察LiveData数据这个observe方法同样进入LiveData.java类中分析。MainThreadpublicvoidobserve(NonNullLifecycleOwner owner,NonNullObserver?superTobserver){// 1assertMainThread(observe);if(owner.getLifecycle().getCurrentState()DESTROYED){// 2return;}// 3LifecycleBoundObserver wrappernewLifecycleBoundObserver(owner,observer);ObserverWrapper existingmObservers.putIfAbsent(observer,wrapper);if(existing!null!existing.isAttachedTo(owner)){thrownewIllegalArgumentException(Cannot add the same observer with different lifecycles);}if(existing!null){return;}// 4owner.getLifecycle().addObserver(wrapper);}MainThreadpublicvoidobserveForever(NonNullObserver?superTobserver){assertMainThread(observeForever);AlwaysActiveObserver wrappernewAlwaysActiveObserver(observer);ObserverWrapper existingmObservers.putIfAbsent(observer,wrapper);if(existing instanceof LiveData.LifecycleBoundObserver){thrownewIllegalArgumentException(Cannot add the same observer with different lifecycles);}if(existing!null){return;}wrapper.activeStateChanged(true);}这里我贴出了两个观察方法。observe方法不需要自己手动清理观察者,当LifecycleOwner进入DESTROYED状态时会自动移除观察者。下面这个observeForever会一直观察不需要传入lifecycleOwner,但是需要自己在不用时销毁removeObserver。// 1第一步要验证这个方法是否在主线程证明该方法必须要在主线程调用。否则会抛出异常崩溃// 2第二步是判断当LifecycleOwner进入DESTROYED状态时自动移除观察者。这个owner就是我们调用该方法时传入的owner;// 3第三步出现了新的观察类LifecycleBoundObserver可以看到它实现了LifecycleEventObserver这个在我们学习Lifecycle的时候有讲过主要是通过onStateChanged来观察生命周期可以看下面的代码。// 4核心。owner.getLifecycle().addObserver(wrapper);兜兜转转又回到了Lifecycle里面把这个观察者添加到lifecycle里面。之前在Lifycycle原理篇有讲过为lifycycle添加观察者等lifecycleowner的生命周期变化就会出发lifecycle event事件。classLifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver{NonNullfinalLifecycleOwner mOwner;LifecycleBoundObserver(NonNullLifecycleOwner owner,Observer?superTobserver){super(observer);mOwnerowner;}OverridebooleanshouldBeActive(){returnmOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);}OverridepublicvoidonStateChanged(NonNullLifecycleOwner source,NonNullLifecycle.Event event){Lifecycle.State currentStatemOwner.getLifecycle().getCurrentState();if(currentStateDESTROYED){removeObserver(mObserver);return;}Lifecycle.State prevStatenull;while(prevState!currentState){prevStatecurrentState;activeStateChanged(shouldBeActive());currentStatemOwner.getLifecycle().getCurrentState();}}OverridebooleanisAttachedTo(LifecycleOwner owner){returnmOwnerowner;}OverridevoiddetachObserver(){mOwner.getLifecycle().removeObserver(this);}}接着往下看这个代码activeStateChanged(shouldBeActive());能看到当前状态是active的时候会分发数据dispatchingValue(this);voidactiveStateChanged(boolean newActive){if(newActivemActive){return;}// immediately set active state, so wed never dispatch anything to inactive// ownermActivenewActive;changeActiveCounter(mActive?1:-1);if(mActive){dispatchingValue(this);}}dispatchingValue在LiveData中这个方法用于将最新的值分发给观察者。voiddispatchingValue(NullableObserverWrapper initiator){// 首先检查是否正在分发值mDispatchingValue为true。// 如果是则设置mDispatchInvalidated true并立即返回。// 这意味着如果有递归调用它会标记当前分发无效让外层循环知道需要重新执行。if(mDispatchingValue){mDispatchInvalidatedtrue;return;}mDispatchingValuetrue;do{mDispatchInvalidatedfalse;if(initiator!null){considerNotify(initiator);initiatornull;}else{for(IteratorMap.EntryObserver?superT,ObserverWrapperiteratormObservers.iteratorWithAdditions();iterator.hasNext();){considerNotify(iterator.next().getValue());//循环结束后检查mDispatchInvalidated标志。// 如果为true表示在分发过程中发生了无效化//通常是因为有新的数据变化导致需要重新分发那么循环会再次执行//重新开始分发。否则退出循环。if(mDispatchInvalidated){break;}}}}while(mDispatchInvalidated);mDispatchingValuefalse;// 分发结束}上述核心方法considerNotify(initiator);considerNotify是 LiveData 中实际触发观察者回调的关键方法它在dispatchingValue中被调用用于向单个观察者派发数据。observer.mObserver.onChanged((T) mData);确保只有在观察者处于正确状态且数据确实更新时才通知同时维持了与 Lifecycle 组件的生命周期安全集成。privatevoidconsiderNotify(ObserverWrapper observer){if(!observer.mActive){return;}if(!observer.shouldBeActive()){observer.activeStateChanged(false);return;}if(observer.mLastVersionmVersion){// 这块是来判断黏性数据的return;}observer.mLastVersionmVersion;observer.mObserver.onChanged((T)mData);}这里最后就是我们回调的onChanged方法那我们通过上面的分析就知道livedata通过注册lifecycle观察者在事件变更时能接收到变化。接下来我们继续看第三步第三步 设置LiveData数据使用setValue主线程/postValue子线程的形式去设置Livedata数据因为postValue最终也会调用到setValue,所以我们从postValue()看起protectedvoidpostValue(T value){boolean postTask;// 加同步锁考虑线程安全synchronized(mDataLock){postTaskmPendingDataNOT_SET;mPendingDatavalue;}if(!postTask){return;}// 在这里线程切换到主线程ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);}privatefinalRunnable mPostValueRunnablenewRunnable(){SuppressWarnings(unchecked)Overridepublicvoidrun(){Object newValue;synchronized(mDataLock){newValuemPendingData;mPendingDataNOT_SET;}setValue((T)newValue);}};看上述代码看到在postValue()中将线程切换到主线程中在主线程中又调用了setValue()。至此我们就知道postValue最终也会通过runnable调用到setValue().MainThreadprotectedvoidsetValue(T value){assertMainThread(setValue);mVersion;// 首次-1 - 0mDatavalue;dispatchingValue(null);// null进入for循环加到观察者里}可以看到上面的setValue是必须要在主线程中调用的。如果在子线程调用会抛出异常。接着往下看。mVersion,此时首次进入这个值从-1变成了0同时传入wrapper是null(这个方法我们再第二步中也有描述)voiddispatchingValue(NullableObserverWrapper initiator){if(mDispatchingValue){mDispatchInvalidatedtrue;return;}mDispatchingValuetrue;do{mDispatchInvalidatedfalse;if(initiator!null){considerNotify(initiator);initiatornull;}else{for(IteratorMap.EntryObserver?superT,ObserverWrapperiteratormObservers.iteratorWithAdditions();iterator.hasNext();){considerNotify(iterator.next().getValue());if(mDispatchInvalidated){break;}}}}while(mDispatchInvalidated);mDispatchingValuefalse;}首次mObservers可以有多个是一个map集合。因此进入for循环全部加进来。此时我们再去看considerNotify方法中的version// mLastVersion 为-1// mVersion为0没法进入这里往下走后续走传入的observer不为空的逻辑直接调用。if(initiator!null){considerNotify(initiator);initiatornull;}int mLastVersionSTART_VERSION;// -1privatevoidconsiderNotify(ObserverWrapper observer){if(!observer.mActive){return;}if(!observer.shouldBeActive()){observer.activeStateChanged(false);return;}// 不触发if(observer.mLastVersionmVersion){return;}observer.mLastVersionmVersion;// 直接把数据分发下去。这个数据在这里是指代的订阅之前接设置好的黏性数据哦后续就是订阅之后传入的数据了。observer.mObserver.onChanged((T)mData);}到这里我们先总结下黏性数据的步骤1、在订阅之前先设置好valueliveData.value 202、mVersion 变为03、将设置的value传入mDatamData value;也就是mData 20埋下伏笔4、接着我们订阅观察者。在LifecycleBoundObserver中当我们的owener启动生命周期变化后会通过activeStateChange分发当前数据见下图这里就不走循环了不需要再把observer加到map集合了。5、后面就是considerNotify判断observer.mLastVersion mVersion.这里mLastVersion为-1mVersion在2中变成了0因此无法进入判断。mLastVersion设置为0同时触发我们观察者的onChanged((T) mData)。这里的mData就是什么没错就是那个在1中设置好的数据20小结可以用这张图来表示。下一步可能会讲讲怎么解决数据倒灌黏性数据。ing…
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2423430.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!