notifydatasetinvalidated

作者:黑玉龙

授权原件:https://mp.weixin.qq.com/s/vZsqMG7yna_EIfh75bgz5A

前言

本讲座的主要内容有:

1.LiveData核心方法

2.LiveData原理分析

3.LiveData粘性事件的原因。

一、LiveData 核心方法:

1.LiveData公共方法。

TgetValue()//返回当前值。请注意,在后台线程上调用此方法并不保证您会收到最新的值集。BooleanhasActiveObservers()///如果此LiveData有活动的观察者,则返回true。BooleanhasObservers()///如果此LiveData有观察者,则返回true。void observe(LifecycleOwnerowner,Observer & ltT & gtObserver)//(注册与主机生命周期相关联的观察者)将给定的观察者添加到给定所有者生命周期内的观察者列表中。voidobserveForever(观察者& ltT & gt观察者)//(注册一个观察者,不会被注销,需要自己维护)将给定的观察者添加到观察者列表中。voidremoveObserver(Observer & lt;T & gtObserver)//从观察者列表中删除给定的观察者。voidremovebservers(lifecycleownerw)//删除绑定到给定的所有观察器LifecycleOwner。2.当活动观察器的数量从0变为1时,调用LiveData保护的方法void active ()//(当且仅当存在活动观察器时触发)。当活动观察器的数量从1变到0时调用vodininactive()///(当没有活动观察器时触发)。//这并不是说没有观察者,可能还会有观察者,只是他们的生命周期状态不是开始就是恢复(比如后面栈的“ activity”)。//可以通过检查是否存在观察者hasObservers()。VoidpostValue(Tvalue)//(与setValue相同。不受线程环境限制,)将任务发布到主线程设置给定值。VoidsetValue(Tvalue)//(发送数据,没有活动的观察者时不要分发。仅在主线程中。)设置值。二、分析LiveData原理:1。观察订阅源代码分析;LiveData注册观察者触发消息分发过程的原理分析。

1.1首先看看observe方法源码

注册观察时,可以主动与宿主的生命周期绑定,无需注销:

@ mainthreadpublicfoidveoscope(@ NonNullLifecycleOwnerowner,@ NonNullObserver & lt?superT & gt观察者){//1。断言此方法只能在主线程中调用(如果未在主线程中注册,将引发IllegalStateException异常)assertMainThread(& # 34;观察& # 34;);//2.当当前绑定组件(活动或片段)的状态被破坏时,当前订阅请求if (owner。getlifecycle()。getcurrentstate()= = destroyed){/ignorreturn;}//3.创建一个生命周期感知的观察者包装器类(用生命的边界将注册的观察者包装为观察者);lifecycleboundobserver apper = Newlifecycleboundobserver(所有者,观察者);//4.接下来会判断观察是否已经注册,如果是,会抛出异常,所以需要注意的是,不允许注册观察者rapperexisting = mobservers。反复Putifabsent(观察者、包装器);//5.对应的观察者只能绑定到一个所有者,如果(存在!=null&&!existing . isattachedto(owner)){ thrownewIllegalArgumentException(& # 34;Cannotaddthesameobserver & # 34+"具有不同的生命周期& # 34;);}如果(现有!= null){ return;}//6.通过使用Lifecycle,您可以通过向LifecycleBoundObserver注册观察器来监视主机的生命周期状态的变化。所有者。获取生命周期()。添加观察者(包装器);}摘要:

1、observe只能在主线程调用,如果不在主线程注册会抛IllegalStateException异常2、当前绑定的组件(activity或者fragment)状态为DESTROYED的时候, 则会忽视当前的订阅请求3、内部会创建生命周期感知的观察者包装类LifecycleBoundObserver(把注册进来的observer包装成 一个具有生命周边边界的观察者)4、对应观察者只能与一个owner绑定,不允许重复注册5、最后利用Lifecycle,把观察者注册到LifecycleBoundObserver进去,就能监听到宿主生命周期状态的变化

LifecycleBoundObserver携带了哪些信息,再看看。…

1.2、LifecycleBoundObserver源码:

从以上分析可以看出:

使用Lifecycle,观察者在LifecycleBoundObserver中注册,从而监控主机生命周期状态的变化。

一旦添加了新的观察者,Lifecycle就会将其状态与主机同步,这将触发观察者的onStateChanged方法。

内部会创建生命周期感知的观察者包装类LifecycleBoundObserver(把注册进来的observer包装成 一个具有生命周边边界的观察者)它能监听宿主被销毁的事件,从而主动的把自己反注册,避免内存泄漏此时观察者是否处于活跃状态就等于宿主是否可见, 监听宿主的生命周期,并且宿主不可见时不分发任何数据

LifecycleBoundObserver源代码:

//1.LifecycleBoundObserver是LiveData的内部类,classlifecycleboundserverextedsobserver perimplementlifecycleeventobserver { @ nonnullfinalfilecleownerowner;LifecycleBoundObserver(@ NonNullLifecycleOwnerowner,Observer & lt?superT & gt观察者){super(观察者);mOwner =所有者;} @ overridebooleanshoulbeactive(){//2。观察器是否活动等于主机的状态是否大于或等于已启动;;//如果页面当前不可见,而你发送了一条消息,此时就不会分发,这样可以避免后台任务抢占资源,只有当页面再次可见时才会分发。returnmOwner.getLifecycle()。getCurrentState()。isAtLeast(已启动);} @ OverridepublicvoidonStateChanged(@ NonNullLifecycleOwnersource,@ nonnulllife cycle . event event){//3。如果收到销毁的事件,它将自动解除绑定所有者,如果(owner。getlifecycle()。getcurrentstate () = =销毁){移除观察者(Mob服务器);返回;}//否则说明主机的状态发生了变化。此时会判断主机是否处于主动状态active state changed(应为active());} @ OverridebooleanisAttachedTo(LifecycleOwnerowner){ return mowner = = owner;} @ overrideviddetachobserver(){ mo owner . get life cycle()。remove observer(this);} }//接口,触发观察者的onStateChanged方法//通过生命周期,add observer(observeroserver)//handleLifecycleEvent(event event)//宿主(活动或片段)每次生命周期发生变化时都会回调onStateChange方法。public interface life cycle Observer {/* * * called whanastatetransitioneventoccurs。* * @ paramsourcesourceoftheevent * @ parameventheevent */voidonStateChanged(@ NonNullLifecycleOwnersource,@NonNullLifecycle。event event);在观察器包装器状态改变后,如果观察器是活动的,将触发数据分发过程。

//抽象类privateactclassserverapper { final observer

voiddispatchingValue(@ NullableObserverWrapperinitiator){ if(mDispatchingValue){ mDispatchInvalidated = true;返回;} mDispatchingValue = truedo { mDispatchInvalidated = false如果(发起者!=null){//1。如果传递的观察者不是空,则将数据分发给自己。当观察者新注册时,将触发该过程。initiator = null}else{//2,否则遍历集合中所有注册的观察者,逐个调用considerNotify,为(iterator)分配数据

privatevoidcounternotify(observer rapper observer){//1。如果(!observer . MAC active){ return;}//Checklateststateb4dispatch。maybeitchangedstatebutwedidn & # 39;tgettheeventyet。////westillfirstcheckobserver . activetokeepitastheentranteforevents . soevenif//theobservermovedtoaactivestate,ifwe & # 39VenotReceiveDThatEvent,webetter not//NotifyforamoreDirectableNotification Order。//2.观察器所在的主机是否活动,并将观察器的状态改为falseif(!observer . shouldbeactive()){ observer . activestatechanged(false);返回;}//3.这里判断观察者接收消息的次数是否大于或等于观察者发送消息的次数(观察者创建之初威瑞森=-1)如果(观察者。mlastversion >:= mv version){ return;}//4、计算最近一次发送消息的次数observer . mlastversion = mv version;//5.onChanged方法观察器。将在此处执行传入观察者的mobserver.on changed ((t) mdata );}2、setValue发送源代码分析2.1 setValue源代码分析

@ MainThreadprotectedvoidsetValue(Tvalue){ assertMainThread(& # 34;setValue & # 34);//这个mVersion是属于LiveData的,然后只有setValue的时候才会增加1m version++(postValue最终会调用setValue);mData =值;dispatchingValue(空);}2.2与观察者分析相同,dispatchingValue(this)数据分发流程控制:(内部实现considerNotify(initiator)方法)

voiddispatchingValue(@ NullableObserverWrapperinitiator){ if(mDispatchingValue){ mDispatchInvalidated = true;返回;} mDispatchingValue = truedo { mDispatchInvalidated = false如果(发起者!=null){//1。如果传递的观察者不是空,则将数据分发给自己。当观察者被新注册时,该过程将被触发。initiator = null}else{//2,否则遍历集合中所有注册的观察者,逐个调用considerNotify,为(iterator)分配数据

privatevoidcounternotify(observer rapper observer){//1。如果(!observer . MAC active){ return;}//Checklateststateb4dispatch。maybeitchangedstatebutwedidn & # 39;tgettheeventyet。////westillfirstcheckobserver . activetokeepitastheentranteforevents . soevenif//theobservermovedtoaactivestate,ifwe & # 39VenotReceiveDThatEvent,webetter not//NotifyforamoreDirectableNotification Order。//2.观察器所在的主机是否活动,并将观察器的状态改为falseif(!observer . shouldbeactive()){ observer . activestatechanged(false);返回;}//3.这里判断观察者接收消息的次数是否大于或等于观察者发送消息的次数(观察者创建之初威瑞森=-1)如果(观察者。mlastversion >:= mv version){ return;}//4、计算最近一次发送消息的次数observer . mlastversion = mv version;//5.onChanged方法观察器。将在此处执行传入观察者的mobserver.on changed ((t) mdata );}综上,LiveData的粘性事件:这种情况称为LiveData的粘性事件。同一个LiveData在更改数据时调用setValue,内部维护的mv version会增加1,mv version的初始值为-1。监听数据变化时,调用observer监听时,每次经过包装器类中的新ObserverWrapper时,内部都会维护一个mLastVersion变量,mLastVersion的初始值也是-1,所以注意,每次执行observer方法时,都会新创建一个内部维护mLastVersion,成为-1结论。因此,只要之前传输过一次数据,之后注册的观察者就会收到之前传输的数据。

这也是为什么通常使用LiveData时,大多数情况下,应用组件的onCreate()方法是开始观察LiveData对象的正确起始点,以避免粘性事件。

后台私信回复1024免费接收SpringCloud、SpringBoot、微信小程序、Ja访谈、数据结构、算法等全套视频资料。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。

发表回复

登录后才能评论