androidlivedata的简单介绍
本篇文章给大家谈谈androidlivedata,以及对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
- 1、Android-LiveData原理解析
- 2、Android中对LiveData的多个请求结果进行合并
- 3、Android LiveData原理
- 4、Android LiveData粘性,粘连,倒灌
- 5、Android LiveData和MutableLiveData使用详解
Android-LiveData原理解析
LiveData是一种具有生命周期感知能力的可观察数据持有类。
LiveData可以保证屏幕上的显示内容和数据一直保持同步。
在项目中,LiveData一般是存放在ViewModel中,以保证app配置变更时,数据不会丢失。
使用流程其实很简单,就是自定义实现一个Observer观察者,然后在Activity或者兆改Fragment中获取到ViewModel,通过ViewModel获取到对应的LiveData,然后给LiveData添加观察者监听,用来监听LiveData中的数据变化,在Observer的onChanged中使用监听回调数据。
在使用LiveData的时候需要注意,LiveData有两个设置数据的方法,一个是setValue,一个是postValue,setValue只能是在主线程使用,而postValue只能在子线程中使用。
LiveData添加观察者监听,可以看到LiveData的observe方法,使用了@MainThread注释,表明该观察者监听添加的方法,只能是在主线程中使用,如果不是在主线程中使用,则会抛出异常。
在LiveData添加观察者的时候,因为LifecycleBoundObserver实际上也是实现了LifecycleEventObserver接口的,所以在Lifecycling.lifecycleEventObserver对观察者对象做封装的时候,也是直接返回传入的观察者对族败判象,不做任何的处理
LifecycleBoundObserver中封装了LifecycleOwner对象和Observer对象,并且实现了LifecycleEventObserver接口,根据Lifecycle的原理,其实我们可以知道,LifecycleRegistry.addObserver方法,添加的就是LifecycleEventObserver实现了对象。
所以在Activity使用LiveData,添加观察者,其实其内部最终还是给Activity的LifecycleRegistry添加观察者,然后根据Activity的生命周期的变化对LiveData进行通知。
postValue的通知更新,其实就是调动任务栈分发任务,而被分发执行的任务实现如下:
从这里可以看到,其实postValue在分发的任务中,其内部实现的依然是setValue()方法,只不过是从子线程切换到了主线程进行执行。做了一次线程的切换。
在postValue方法中,其内部调用的是ArchTaskExecutor的postToMainThread方法。
在这里可以看到mDelegate其实就是DefaultTaskExecutor对象
所以mDelegate.postToMainThread(runnable)其实就是调用了DefaultTaskExecutor.postToMainThread方法。
在这里可以看到,mMainHandler其实就是通过主线程的Looper实例创建的Handler对象,所以这里Handler发送消息执行任务,就是在主线程中执行该任务。
LiveData在分发消息的时候,会调用dispatchingValue方法循环分发,当消息分发完成之后,其实并不会退出do-while循环,还会在调用considerNotify方法的内部调用observer.activeStateChanged(false);继续执行第二次dispatchingValue方法,也就是说递归执行,在第二次执行的时候枯衫,mDispatchingValue = true,就会执行将mDispatchInvalidated = true,那么就会完成dispatchingValue方法的第二次执行,被直接return,那么considerNotify()方法的执行也就完成,此时就会执行considerNotify之后的if条件,因为在dispatchingValue第二次执行的时候将mDispatchInvalidated设置为了true,就直接break跳出了循环,结束了消息的分发。
但是这样的情况,一般是在存在观察者处于ON_STOP或者已经是ON_DESTROY状态的时候。
如果观察者都是处于onResume,那么这个时候会因为mDispatchInvalidated=false而退出了循环,结束分发。
但是如果是先setValue,然后再设置Observer的话。
因为此时设置Observer的时候,当生命周期发生变化的时候,又会调用回调onStateChanged方法,进而调用activeStateChanged方法
因为在添加Observer之前,已经针对该LiveData设置了一个value,此时添加了观察者,那么又因为生命周期发生了变化,那么该观察者在调用dispatchingValue(this);传入的就不是null,则在do-while循环的if判断中,就会执行if条件,进而调用considerNotify()方法给传入的ObserverWrapper实现类分发消息,那么就会把之前设置的消息分发给了该观察者。
这样的情况就是LiveData的粘性事件。即后注册的观察者接收到了之前LiveData设置的value消息。
那么问题又一次来了,什么时候会触发调用LifecycleBoundObserver的onStateChanged方法呢?
通过LiveData的observe方法进行分析,我们可以知道给LiveData添加观察者的时候,其实就是通过给实现了LifecycleOwner接口的Activity的getLifecycle()方法获取到的LifecycleRegistry对象添加观察者,而LifecycleRegistry中的addObserver方法,就会先满足while条件,然后执行了ObserverWithState.dispatchEvent方法,此时就会调用到了LifecycleBoundObserver.onStateChanged方法
这里为什么会满足while条件呢?calculateTargetState会获取当前Activity生命周期状态的前一个和后一个状态,然后取更小的那个状态,在addObserver的时候,calculateTargetState这里如果activity是onStart的状态,那么calculateTargetState取出的就是CREATED状态,如果activity是onResume的状态,那么这里取出的就是STARTED,不管怎么样都会大于INITIALIZED状态,那么就会满足while条件,此时第二个activity是在onCreate生命周期调用observe方法注册Observer
其实这里个人感觉,应该是在addObserver之后,因为第二个Activity(也就是添加addObserver的)发生了生命周期变化,从onCreate变成了onStart,从onStart变成onResume,此时就会调用moveToState,然后就会调用forwardPass(),然后就会分发消息,因为之前已经postValue或者setValue了,那么在这个LiveData里的mData就不会为null,有消息了,就可以优先分发一次。
满足while条件后,就会调用statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));,这里最终就会调用LifecycleBoundObserver的
这里shouldBeActive(),在Activity的最后的生命周期是onResume的时候,就会满足true,那么此时activeStateChanged()传入的参数就是true,而初始的时候,mActive为false
此时mActive就会重新赋值为true,那么就会调用dispatchingValue()方法,此时dispatchingValue()的参数传入this,那么就不会为false。
一般常用的粘性事件解决方案,其实就是hook修改mLastVersion的值,让这个值变成与mVersion的值一致,但是如果是在onResume或者onStart的生命周期去添加注册观察者,那么常见的粘性事件解决方案中,因为会调用super.observe(),那么就会因为在LifecycleRegistry.addObserver方法中,满足while条件,从而又会进行LifecycleBoundObserver的onStateChanged方法的回调,这样又会出现粘性事件。这样的情况的解决方案,其实可以hook修改mVersion的值,在注册观察者之前,改成-1
Android中对LiveData的多个请求结果进行合并
首先,封装一辩败滑个LiveData结果的合并类。通过扩展MediatorLiveData来携腊实现。
然后,结合使用LiveData并合并之枯纳,统一处理结果。
[img]Android LiveData原理
LiveData的特点:
1、采用了观察者模式,数据发生改变的时候,可以自动回调
2、不需要手动处理生命周期,不会因为activity的销毁跟创建而丢失数据
3、不会内存泄漏
4、不需要手动取消订阅,activity在非活动状态下不会收到族知订阅
使用LiveData 主要分两步
接下来我们看一下ObserverWrapper里面的activeStateChanged方法
到此雀庆Observer已经设置完成,我们看一下dispatchingValue。
LiveData有两种设置值的方式,一种是setValue, 只能在主线程,一种是postValue()可以在子线程调用。
检测是不是主线程,然后调用dispatchingValue
considerNotify 调用之前设置的onChanged方法
postValue把定义的mPostValueRunnable加入到一个主线程的兆岁消队列里面,mPostValueRunnable里面直接调用了setValue方法
Android LiveData粘性,粘连,倒灌
工作机制:每次改变LiveData数据都会对数据版本号加1,并触发版本号小于数据版配山本号的观察者培指中监听,触发后观察者的版本号与数据版本号一致。
粘性事件:更新数据后,观察者再订阅,新注册的观察者版本号为-1小雨数据版本号,所以注册时会触发一次数据监听。
数据粘连:LiveData的激活状态标识,会在对应的LifecyOwner执行onStart后设置为true,执行onDestroy后设置为false,在未激活状态下无论发生多少次改逗培变,只有最后一次数据会发送给观察者。
数据倒灌:由于LiveData的激活状态标识先变为false,再变为true,导致触发小于数据版本号的所有观察者的监听。常见场景为:使用ViewModel持有LivaData,并在生命周期内创建监听对象,则在Activity由于屏幕翻转等配置变化引发onDestroy时,ViewModel不会执行clear,因此保留了内部的LiveData,而在生命周期内重新创建监听对象的版本号为-1,所以在onStart之后会触发观察者监听。
解决方案:
1.修改version
2.复写LiveData
3.包装事件,事件内带处理状态
2022-04-11
Android LiveData和MutableLiveData使用详解
参考链接:
首先LiveData其实与数据实体类(Plain OrdinaryJava Object)是一样的东西,它负责暂存数据。其次LiveData也是一个观察者模式的数据实体类,它的观察者可以回调数据是否已经更新.
LiveData与MutableLiveData的其实在概念上是一模一样的,唯一几个的区别如下:
继承LiveData并且在泛型里写下你的实体类
postValue(this) 这个方法是用于回调数据更新的方法. 你可以在你需要被观察的数据里添加.
调用 ViewModelProvider of(@NonNull Fragment fragment, @Nullable Factory factory) 方法,只不过,需要多传递一个 factory 参数。
我们的做法是:实现 Factory 接口,重写 create 方法,在create 方法里面调用相应的构造函数凯纤,返回相应的实例。
MutableLiveData只是作用于变量所以我们直接就可以在ViewModel里实例化它,并且在泛型里标注变量的类型.
我们回过头来再来看一下 ViewModelProvider 的 of 方法,他主要有四个方法,分别是
1,2 方法之间的主要区别是传入 Fragment 或者 FragmentActivity。而我们知道,通过 ViewModel of 方法创建的 ViewModel 实例, 对于同一个 fragment 或者 fragmentActivity 实例,ViewModel 实例是相同的,因而我们可以利用该特点,在 Fragment 中创建 ViewModel 的时候,传入的是 Fragment 所依附的 Activity。因而他们的 ViewModel 实例是相同的,从而可以做到共享数据。
说到全局共享数据,我们想一下我们的应用全景,比如说我的账户数据,这个对于整个 App 来说,肯定是全局共享的。有时候,当我们的数据变化的时候,我们需要通知我们相应的界面,刷新 UI。如果用传统的方式来实现,那么我们一般才采取观察者的方式来实现,这样,当我们需要观察数据的时候,我们需要添加 observer,在界面销毁的时候,我们需要移除 observer。
但是,如果我们用 LiveData 来实现的话,它内部逻辑都帮我们封装好了,我们只需要保证LiveData 是单例的就ok,在需要观察的地方调用 observer 方法即可。也不需要手动移除 observer,不会发生内存泄漏盯森仿,方便快捷。
postValue的特性如下:
setValue()的特性如下:
返回当前值。 注意,在后台线程上调用此方法并不能保证将接收到最新的春或值。
移除指定的观察者
如果此LiveData具有活动(Activity或者Fragment在前台,当前屏幕显示)的观察者,则返回true。其实如果这个数据的观察者在最前台就返回true,否则false。
当活动观察者的数量从0变为1时调用。这个回调可以用来知道这个LiveData正在被使用,因此应该保持最新。
当活动观察者的数量从1变为0时调用。即观察者的生命周期状态没有STARTED or RESUMED
如果此LiveData具有观察者,则返回true。
设置此LiveData数据当前activity或者Fragment的观察者,会给此activity或者Fragment在前台时回调数据。
移除当前Activity或者Fragment的全部观察者,在使用了observeForever 时调用,即监听了应用在前台状态时的LiveData值变化
关于androidlivedata和的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。