1.介绍:LiveData是一种可观察的数据存储器类,LiveData具有生命周期的感知能力,可感知view层生命周期,在数据发生变化的时候(view活跃的时候,销毁时停止更新),可以通知到添加进来的观察者
LiveData是个抽象类,主要使用其子类MutableLiveData
2.基本使用
2.1 observe方法添加观察者
首先在逻辑层(后面MVVM架构中在ViewModel层)添加属性,是要监听的数据,放入MutableLiveData容器中
其次,一般通过Model层获取的数据,这里设置数据,采用postValue的方式,保证数据在主线程,如果使用setValue可能有异步线程的风险
最后在view添加observer即可在数据发生变化的时候,来更新UI,这里使用的observe方法添加观察者,参数1是owner,这里传入this,参数2是观察者对象,这种通过observe方法添加观察者,在view不活跃(活跃指的是:STARTED、RESUMED状态)的时候,不会去更新数据,也不会更行相应的UI
2.2 observeForever方法添加观察者
定义观察的数据和设置数据都和前面是一样的
在添加观察者的时候是不一样的,采用observeForever方法添加观察者需要自己在view的onDestroy中手动去移除观察者removeObserver 使用LiveData的observeForever进行监听, UI不可见时也会进行更新数据,同时需要手动的移除mForeveObserver 因为需要手动移除,所以这里需要实现内部类,实现Observer接口 否则匿名内部类无法移除
添加观察者
手动移除观察者
3.LiveData实现数据共享
需求:音乐播放器中,在主界面PlayerActivity值需要关心当前的播放状态mLivePlayerState,在另外一个悬浮窗界面也要关心当前的播放状态,可以使用LiveData进行数据共享
创建LivePlayerState类继承LiveData
package com.example.jetpackbysob.datanotifyuiupdatetest
import androidx.lifecycle.LiveData
/**
* Project_name:JetPackBySob
* Created by:ChenFuXu.
* Date: 2022/5/10 23:23
*/
class LivePlayerState private constructor() : LiveData<PlayerPresenter.PlayState>() {
companion object {
val instance by lazy {
LivePlayerState()
}
}
public override fun postValue(value: PlayerPresenter.PlayState?) {
super.postValue(value)
}
}
首先在逻辑层或ViewModel层创建需要监听是数据mLivePlayerState
其次在Model层数据回来后对监听的数据进行设置
在PLayerActivity中创建内部类LivePlayerStateObserver,实现Observer接口
然后在observeForever和removeForever添加和移除观察者即可
同样的,在FlowPlayerControllerActivity悬浮窗中先创建内部类FlowPlayerStateObserver实现Observer接口即可
因为mPlayerPresenter是通过单例模式获取的,所以两个view的Presenter是同一个实例对象,里面的mLivePlayerState播放状态也是同一个数据,所以只是观察者不一样,这里就实现了不同view的数据共享
4.LiveData源码分析
问题1:LiveData是如何保证更新数据的时候是在主线程更新的?
在LiveData中的postValue方法可以保证在主线程更新数据,传进来的value值会赋值给mPendingData,通过ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable)运行在主线程,在mPostValueRunnable任务中会调用setValue方法
在setValue中会进行断言,如果不是主线程,会抛出异常
问题2:LiveData如何通知观察者数据更新了?
首先先看下两种添加观察者的方式observe和observeForever
然后两种添加观察者的方式都将添加进来的观察者添加到了mObservers集合中了
这里我们回到设置数据的setValue方法,每次设置value,首先mVersion版本号增加,然后调用dispatchingValue方法处理分发value
在处理分发value时,会取出添加到mObservers中的所有观察者,调用considerNotify方法
在considerNotify方法中,如果observer不活跃,直接返回了,前面分析中,observe方法的会根据当前的状态进行判断,observeForever会一直返回true,最后调用观察者的observer的onChanged方法
即通知到了我们添加的观察者了
问题3:LiveData如何感知View层的生命周期?