当前位置: 首页 > 科技观察

Android进阶源码LiveData工作原理详解

时间:2023-03-13 00:40:21 科技观察

本文转载自微信公众号《Android开发与编程》,作者Android开发与编程。转载本文请联系Android开发编程公众号。前言LiveData是一个可观察的数据存储类。与常规可观察类不同,LiveData具有生命周期感知能力,这意味着它遵循其他应用程序组件(例如活动、片段或服务)的生命周期。这种意识确保LiveData仅更新处于活动生命周期状态的应用程序组件观察者。LiveData本身就是一个观察者,观察组件的Lifecycle,也是观察者。当数据发生变化时,必须通知数据的观察者。前面我们讲解了Lifecycle实现的原理。今天我们就来看看LiveData源码高级生命周期组件的原理分析一、livedata在app中的应用1、使用livedata的步骤创建一个LiveData的实例,用来保存某类数据。这通常在您的ViewModel类中完成;创建一个Observer对象,该对象定义一个onChanged()方法,该方法控制LiveData对象持有的数据发生变化时发生的情况。您通常在UI控制器中创建Observer对象,例如活动或片段;使用Observer方法将Observer对象附加到对象。这个方法接受一个对象。这会将对象订阅到对象,以便通知更改。您通常将此对象附加到UI控制器,例如活动或片段;2.viewModellivedatapublicclassNameViewModelextendsViewModel{//CreateaLiveDatawithaStringprivateMutableLiveDatamCurrentName;publicMutableLiveDatagetCurrentName(){if(mCurrentName==null){mCurrentName=newMutableLiveData();}returnmCurrentName;中定义了一个简单的livedata例子;}//RestoftheViewModel...}在activity或Fragment中实现监听更新uipublicclassNameActivityextendsAppCompatActivity{privateNameViewModelmModel;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(State)savedInstance;//Othercodetosetuptheactivity...//GettheViewModel.mModel=ViewModelProviders.of(this).get(NameViewModel.class);//CreatetheobserverwhichupdatestheUI.finalObservernameObserver=newObserver(){@OverridepublicvoidonChanged(@NullablefinalStringnewName){//更新UI,在本例中为aTextView.mNameTextView.setText(newName);//注意MVVM中不是这样写的,这里只是单行绑定}};//ObservetheLiveData,将此活动作为LifecycleOwnerandtheobserver.mModel.getCurrentName().observe(this,nameObserver);//注意这里使用了lambda表达式,没有使用Java8,可以写的更简洁,}}更新livedata对象,调用setValue(T)该示例将导致观察者onChanged()使用此值调用其ui以刷新该示例显示按下按钮,但可以调用setValue()或postValue()来更新mName的原因有很多,包括响应网络请求或数据库加载的完成;在所有情况下,调用setValue()或postValue()都会触发观察者并更新UI;mButton.setOnClickListener(newOnClickListener(){@OverridepublicvoidonClick(Viewv){StringanotherName="JohnDoe";mModel.getCurrentName().setValue(anotherName);}});mButton.setOnClickListener(newOnClickListener(){@OverridepublicvoidonClick(Viewv){StringanotherName="JohnDoe";mModel.getCurrentName().setValue(anotherName);}});二、livedata原理详解1.observe方法首先,该方法只能在主线程中进行注册和观察;官方文档说LiveData只有在active生命周期才有效,所以从一开始就判断是否为Lifecycle.Stete.DESTROYED。;然后是最后一行配准观察。想知道Lifecycle.addObserver是干什么的可以看AndroidLifecycle的实现原理;//map的key是LiveData数据观察者,value是组件的Lifecycle观察者。privateSafeIterableMap,ObserverWrapper>mObservers=newSafeIterableMap<>();@MainThreadpublicvoidobserve(@NonNullLifecycleOwnerowner,@NonNullObserverobserver){assertMainThread("observe");//判断当前生命周期的状态if(owner.getLifecycle().getCurrentState()==DESTROYED){//ignorereturn;}//生命周期的生命周期变化逻辑在这里LifecycleBoundObserverwrapper=newLifecycleBoundObserver(owner,observer);//mObservers保存ObserverWrapperexisting=mObservers.putIfAbsent(observer,wrapper);if(existing!=null&&!existing.isAttachedTo(owner)){thrownewIllegalArgumentException"+lihisameobserver";}if(existing!=null){return;}//在生命周期owner.getLifecycle().addObserver(wrapper);}中感知生命周期变化2.LifecycleBoundObserverLifecycleBoundObserver继承ObserverWrapper并实现LifecycleEventObserver接口ObserverWrapper用于判断组件当前是否处于活动状态;LifecycleEventObserver是Lifecycle的观察者,重写了onStateChanged方法。当Lifecycle生命周期发生变化时,会在这个方法中接收到,LiveData也能感知到。如果组件的生命周期为DESTROYED,那么观察将被移除;到这里LiveData已经完成了组件生命周期感知的注册,可以开始发送数据了;tolifecyclefinalLifecycleOwnermOwner;LifecycleBoundObserver(@NonNullLifecycleOwnerowner,Observerobserver){super(observer);mOwner=owner;}/*判断当前组件是否激活*/@OverridebooleanshouldBeActive(){returnmOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);}@OverridepublicvoidonStateChanged(@NonNullLifecycleOwnersource,@NonNullLifecycle.Eventevent){//获取当前生命周期状态Lifecycle.StatecurrentState=mOwner.getLifecycle().getCurrentState();//如果组件已经被销毁,移动除了观察;activeStateChanged(shouldBeActive());currentState=mOwner.getLifecycle().getCurrentState();}}/*判断是否绑定*/@OverridebooleanisAttachedTo(LifecycleOwnerowner){returnmOwner==owner;}/*移除观察*/@@OverridevoiddetachObserver(){mOwner.getLifecycle().removeObserver(this);}}3.activeStateChangedObserverWrapper这个类中有一个方法,在后面的粘性事件中会用到;voidactiveStateChanged(booleannewActive){//如果组件状态没有改变,则returnif(newActive==mActive){return;}//立即设置activestate,sowe'dneverdispatchanythingtoinactive//ownermActive=newActive;changeActiveCounter(mActive?1:-1);//如果是active,则发送数据if(mActive){dispatchingValue(this);}}4.发送数据分析4.1.PostValue向主线程发送数据该方法的核心是利用主线程Handler发送数据,一步一步拆解分析;protectedvoidpostValue(Tvalue){booleanpostTask;//locksynchronized(mDataLock){postTask=mPendingData==NOT_SET;//保存要发送的数据valuemPendingData=value;}if(!postTask){return;}//使用主线程Handler发送ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);}4.2、postValue其实就是postValue中setValue要发送的Runnable,可以看到最后一行是setValue方法,数据也是之前保存的mPendingData,只不过这里给newValue;privatefinalRunnablemPostValueRunnable=newRunnable(){@SuppressWarnings("unchecked")@Overridepublicvoidrun(){ObjectnewValue;synchronized(mDataLock){newValue=mPendingData;mPendingData=NOT_SET;}setValue((T)newValue);}};4.3、postToMainThread主线程HandlerArchTaskExecutor类postToMainThread方法,实际就是DefaultTaskExecutor类执行postToMainThread方法;publicclassArchTaskExecutorextendsTaskExecutor{@NonNullprivateTaskExecutormDelegate;@NonNullprivateTaskExecutormDefaultTaskExecutor;privateArchTaskExecutor(){mDefaultTaskExecutor=newDefaultTaskExecutor();mDelegate=mDefaultTaskExecutor;}...@OverridepublicvoidpostToMainThread(Runnablerunnable){mDelegate.postToMainThread(runnable);}...}4.4、我们知道的DefaultTaskExecutor类是DefaultTaskExecutor.postToMainThread,直接看这个方法就好了,哎呀,代码太熟悉了,创建一个Handler,传入的是Looper.getMainLooper(),也就是主线程Handler,然后是post消息;publicclassDefaultTaskExecutorextendsTaskExecutor{@NullableprivatevolatileHandlermMainHandler;@OverridepublicvoidpostToMainThread(Runnablerunnable){if(mMainHandler==null){synchronized(mLock){if(mMainHandler==null){mMainHandler=createAsync(Looper.getMainLooper());}}}//noinspectionConstantConditionsmMainHandler.post(可运行);}}4.5。setValue方法mVersion在初始化构造方法中被赋值,为-1。每设置一次Value,版本号就会改变一次;setValue是使用mData保存值,然后交给dispatchingValue方法处理;@MainThreadprotectedvoidsetValue(Tvalue){assertMainThread("setValue");mVersion++;mData=value;dispatchingValue(null);}4.6、dispatchingValue方法setValue使用该方法,传入的initiator为空,然后遍历mObservers保存的观察者发送数据;@SuppressWarnings(“WeakerAccess”)/*syntheticaccess*/voiddispatchingValue(@NullableObserverWrapperinitiator){if(mDispatchingValue){mDispatchingInvalidated=true;return;}mDispatchingValue=true;do{mDispatchInvalidated=false;if(initiator!=null){//粘性事件,为单个观察者接受数据地图.入口,ObserverWrapper>>iterator=mObservers.iteratorWithAdditions();iterator.hasNext();){considerNotify(iterator.next().getValue());if(mDispatchInvalidated){break;}}}}while(mDispatchInvalidated);mDispatchingValue=false;}4.7、considerNotify判断发送数据这里先判断组件是否激活并判断粘性事件,然后使用mVersion判断数据是否已经发送,最后将数据发送到theobserverprivatevoidconsiderNotify(ObserverWrapperobserver){//组件是否激活if(!observer.mActive){return;}//检查lateststateb4dispatch.Maybeitchangedstatebutwedidn'tgettheeventyet.///westillfirstcheckobserver.activetokeepitastheentranceforevents.Soevenif//theobservermovedtoanactivestate,ifwetablenotreceivedthatder/sticky/noticorifyevent(!observer.shouldBeActive()){observer.activeStateChanged(false);return;}//检查数据是否已经发送if(observer.mLastVersion>=mVersion){return;}observer.mLastVersion=mVersion;//发送资料observer.mObserver.onChanged((T)mData);}5.粘性事件分析粘性事件是先发送数据,之后注册观察者接收消息;我们从LiveData.observe开始,新的页面注册了LiveData观察者,同时也注册了Lifecycle观察者;当新的页面生命周期发生变化时,会执行LifecycleBoundObserver.onStateChanged方法;接下来的activeStateChanged方法,因为是新页面,组件状态是active的,进入dispatchingValue方法;dispatchingValue传入的当前新页面发起者不为空,只会向当前观察者发送数据;总结:1.当LifecycleOwner生命周期从inactive变为active时:AddLivedata当一个观察者关联一个LifecycleOwner时,观察者被打包成一个LifecycleBoundObserver并关联LifecycleOwner的getLifecycle。当LifecycleBoundObserver的生命周期发生变化时,会调用LifecycleBoundObserver的onStateChanged方法,判断当前生命周期和上一个生命周期是否是同一类型(active或inactive),如果是则直接返回,避免重复通知(startnotification,resumedoesnot需要通知),如果不是同一个类型,且当前生命周期处于激活状态,调用dispatchingValue方法通知观察者判断LifecycleOwner是否激活。如果有,将Livedata中持有的最新更新更新给观察者;2、当Livedata中的值发生变化时:同样调用dispatchingValue判断LifecycleOwner是否活跃。Active状态,如果有则遍历通知所有观察者;