本站提倡有节制游戏,合理安排游戏时间,注意劳逸结合。

【伪原创程序源码】【新版双端源码】【哆米街源码】livedata源码

2024-11-19 00:49:36 来源:百科 分类:百科

1.MutableLiveData与LiveData区别:可变与不可变
2.LiveData 面试题库、源码解答、源码源码分析
3.LiveDataBus
4.源码解读最详细的源码LiveData分析,从未如此丝滑

livedata源码

MutableLiveData与LiveData区别:可变与不可变

       ä¹‹å‰çœ‹åˆ°å¾ˆå¤šä¸­æ–‡åšå®¢è¯´ï¼š

        看的我是一头雾水,于是去StackOverflow搜了下, 高赞答案 却主要在说:

        如果我们进一步看看MutableLiveData.java仅有多行的源码,就会发现确实后者说的对,MutableLiveData仅仅是暴露出来了setValue和postValue方法:

        最后,在Android官方的 应用架构指南 里,也同时用到了二者。

        它是在ViewModel内部使用了private的MutableLiveData实例,但对外暴露的是LiveData类型,按我的理解,目的应该是防止误修改吧。

LiveData 面试题库、源码解答、源码源码分析

       LivaData 的源码伪原创程序源码面试题库与解答、源码分析

        作者:唐子玄

       1. LiveData 如何感知生命周期的源码变化?

       LiveData 在常规的观察者模式上附加了条件,若生命周期未达标,源码即使数据发生变化也不通知观察者。源码这通过 Lifecycle 实现,源码Lifecycle 是源码生命周期对应的类,提供了添加/移除生命周期观察者的源码方法,并定义了全部生命周期的源码状态及对应事件。要观察生命周期,源码新版双端源码需要实现 LifecycleEventObserver 接口,源码并注册给 Lifecycle。除了生命周期观察者外,还有数据观察者,数据观察者会与 LifecycleOwner 进行绑定。

       2. LiveData 是如何避免内存泄漏的?

       内存泄漏是因为长生命周期的对象持有了短生命周期对象。在观察 LiveData 数据的代码中,Observer 作为界面的匿名内部类,它会持有界面的引用,同时 Observer 被 LiveData 持有,LivData 被 ViewModel 持有,而 ViewModel 的生命周期比 Activity 长。最终的哆米街源码持有链导致内存泄漏。LiveData 帮助避免内存泄漏,在内部 Observer 会被包装成 LifecycleBoundObserver,这实现了生命周期感知能力,同时它还持有了数据观察者,具备了数据观察能力。

       3. LiveData 是粘性的吗?若是,它是怎么做到的?

       是的,LiveData 是粘性的。数据是持久的,意味着它不会因被消费而消失。当 LiveData 值更新时,会通知所有观察者。这一过程通过一个 Map 结构保存了所有观察者,世界之声网站源码并通过遍历 Map 并逐个调用 considerNotify() 方法实现。观察者会被包装在 LifecycleBoundObserver 中,它具备了生命周期感知能力,同时持有了数据观察者。当组件生命周期发生变化时,会尝试将最新值分发给该数据观察者。

       4. 粘性的 LiveData 会造成什么问题?怎么解决?

       粘性的 LiveData 可能导致数据重复消费或消费逻辑混乱。解决方案包括使用带消费记录的值、带有最新版本号的观察者、SingleLiveEvent 等。其中,使用 SingleLiveEvent 可以根据数据的分类(暂态数据或非暂态数据)来选择性地利用或避免粘性。

       5. 什么情况下 LiveData 会丢失数据?

       在高频数据更新的摩贝积分源码场景下使用 LiveData.postValue() 时,如果在这次调用和下次调用之间再次调用 postValue(),则会导致数据丢失,因为值先被缓存,再向主线程抛出分发值的任务。这与 LiveData 的设计和更新机制有关。

       6. 在 Fragment 中使用 LiveData 需注意些什么?

       在 Fragment 中使用 LiveData 时,应当使用 viewLifecycleOwner 而非 this。避免因生命周期不一致导致的额外订阅者问题。使用 SingleLiveEvent 可以解决数据重复消费问题。

       7. 如何变换 LiveData 数据及注意事项?

       androidx.lifecycle.Transformations 提供了变换 LiveData 数据的方法,如 map()。需要注意数据变换操作应避免阻塞主线程,可使用 CoroutineLiveData 来异步化数据变换。

LiveDataBus

        LiveDataBus是基于LiveData实现的类似EventBus的消息通信框架,它是基于LiveData实现的,完全可以代替EventBus,RxBus;

        LiveDataBus的主要是基于发布订阅设计模式,发布订阅模式定义了一种 “一对多” 的关系,和观察者模式是完全不同的两个设计模式;

        下面详细介绍核心类LiveData

        LiveData是一个可以被观察的数据holder,并且可以自动感知控件的生命周期,不会发生内存泄漏;

        LiveData需要一个观察者对象,当LiveData的值发生改变时,观察者会察觉到这个改变;

        使用livedata注册观察者监听

        使用livedata发送消息给观察者

        LiveData其实就是一个存放数据的holder,类似ViewHolder的holder,存放在LiveData里的数据会拥有LiveData的特性;

        LiveData是Android Architecture Components的一个类;这个类是谷歌在Google I/O 发布一套帮助开发者解决Android架构设计的方案。这个类有四个核心,后续会一一介绍;

        用第一代LiveDataBus订阅

        发送消息

        至于说他是第一代bus,说明肯定有问题,问题就是在post或者set一个value后,只要在一个frag/act里observe了,无论组件是否启动,都会收到value,即当在act1中post了,在act2中observe,但是post的时候act2没有运行,当启动act2,收到了value。收到了订阅前的消息

        通过查看LiveData的源码发现setValue()开始,依次调用了

dispatchValue()-> considerNotify()-> observer.onChanged()

        postValue()会调用setValue()所以同理;

        这就解释了为什么我们可以在observer中收到post来的value,为什么act2不运行也可以收到value;

        我们注意到当observer.mLastVersion >= mVersion的时候会直接return,不调用onChanged从而解决上面的问题。

        我们需要拿到mLastVersion,就需要拿到observer对象,顺着源码发现observer对象存在mObservers的map中;我们自定义一个mutableLiveData,改写他的observe(),在observe()中,通过反射拿到mObservers对象,从而拿到observer.mLastVersion,将mVersion赋值给他;

        hook的作用相当于 在observe()调用后执行observer.mLastVersion = mVersion; 让considerNotify()直接return,可是我们如何收到订阅后的post呢?因为只有订阅的时候才会hook,在hook后,我们调用post(),会mVersion++,所以在判断 if (observer.mLastVersion >= mVersion) 的时候就又会是false了;

源码解读最详细的LiveData分析,从未如此丝滑

       本文深入解析LiveData在Android开发中的实现机制及用法,内容涵盖LiveData的生命周期感知、观察者注册、事件回调机制、数据更新以及解决粘性事件问题。通过分析LiveData的源码,以期读者能够深入理解LiveData的运作原理,从而在实际开发中灵活运用。

       首先,LiveData是一种数据存储类,与传统的可观察类相比,具有生命周期感知能力。这意味着LiveData只会更新处于活跃生命周期状态的组件观察者,确保了数据的实时性和安全性。其感知能力基于LifecycleOwner接口,使得活动组件能够安心观察LiveData,无需担心组件生命周期变化导致的数据泄露。

       在注册观察者时,LiveData内部通过LifecycleBoundObserver进行封装,确保只有处于活跃状态的组件才能成功注册。当组件进入DESTROYED状态时,观察者会自动移除,从而实现自动取消注册,避免了额外的代码实现。

       当组件状态发生改变时,LiveData会通过Lifecycle的onStateChanged方法通知其内部的LifecycleBoundObserver,从而触发观察者回调。观察者在被移除或组件状态改变为DESTROYED时,不会收到任何通知。这确保了数据的实时性和组件的资源管理。

       对于数据更新,LiveData提供postValue和setValue方法。setValue直接在主线程执行,而postValue则在主线程执行后调用setValue,确保数据更新的同步性。这些方法最终都会触发观察者回调,实现数据的实时更新。

       观察者永久订阅(observeForever)机制则确保了即使观察者在组件销毁后被重新创建,也能接收到数据更新。通过AlwaysActiveObserver类实现,该类不依赖于组件的生命周期状态,确保了观察者状态的始终活跃。

       在处理粘性事件时,LiveData通过在考虑通知方法中进行版本判断,确保只在观察者版本更新时发送数据。当新观察者订阅时,其版本尚未被初始化,导致旧值发送,这是粘性事件发生的根本原因。解决这一问题,需要确保观察者版本的正确性,避免不必要的数据发送。

       综上,LiveData的源码解析涵盖了其核心机制、注册与取消注册流程、事件回调机制、数据更新方式以及解决粘性事件的方法。通过深入理解LiveData的工作原理,开发者能够在实际项目中高效地管理数据更新和组件生命周期,实现更加流畅和安全的用户体验。

相关推荐
一周热点