一 概述
LiveData 是一种可观察的存储数据类型。与常规的可观察类不同,LiveData 可以感应 Activity、Fragment 或 Service 的生命周期。只会通知处于活跃生命周期状态的观察者。比如当观察者生命周期处于 STARTED 或 RESUMED状态的时候,此时的状态包括 生命周期处于 onStart(),onResume(),onPause() 三种,LiveData才会去通知。同时,当观察者处于 DESTROYED 时,LiveData会移除观察者。不用担心泄漏。当 Activty 或者 Fragment 处于 onStart(),onResume(),onPause() 的生命周期下,会接收到 ,onStop 是收到的
二 LiveData优点
-
确保UI与数据匹配 LiveData本身用的就是观察者模式,当数据源改变的时候会通知观察者,及时更新UI
-
没有内存泄漏 观察者是绑定到 Lifecycle 对象上的,当Lifecycle处于destory的时候会自动清理这个观察者
-
不会因为 Activity处于onStop的状态 而 crash 如果观察者的生命周期处于 inactive (不活跃)状态是不会收到事件的,比如回退栈的Activity
-
不需要手动处理生命周期 LiveData可以感知被绑定的组件的生命周期,只有在活跃状态才会通知数据变化。
-
始终保持最新数据 如果 生命周期 处于非活跃状态,当他再次进入活跃状态的时候,他会拿到最新的数据,并且更新。比如回退栈中的 Activity 在onStop的时候,处于不活跃状态,此时不会通知Activity的,当Activity 再次处于onStart 或者 onResume的时候,再次拿到最新的数据
-
解决了通过 configuration 改变的问题 如果由于 configuration 改变(旋转屏幕)而重新创建的Activity或者Fragment,它会立即拿到最新的数据
-
共享资源(我感觉主要是在本app中实现EventBus的作用) 您可以使用单一实例模式扩展 LiveData 对象以封装系统服务,以便在app中共享它们
缺点是有的
- 默认是粘性事件,如果你提前更改了一个LiveData值,如果此时再打开一个Activity 的话 就会根据version立即执行 监听事件,有的时候不是我们要的,可以在写一个类继承MutilLivewData,当 observe 的时候,我们我们可以通过反射 把mLastVersion 修改成 当前LiveData的 mVersion ,让他们相等
- 在Activity 和 Fragment 的生命周期 的onStop的时候 并不会 回调监听,需要再执行 onResume的时候,才去更改
- postValue 会丢失数据,原因是,如果连续两次postValue 他用的一个runable ,只是更改了里面的值,
- 当onStop 的时候,如果 setValue 好几次,在onResume的时候 只会执行最后的一个
大概原理
- 当我们调用 liveData.observe(this, Observer),他会注册这个Actvitiy生命周期回调 owner.getLifecycle().addObserver(wrapper);
- 当Activity的生命周期触发的时候,他会判断是否 这个LiveData的version 大于 这个 Observer mLastVersion ,如果大于,直接触发,同时只有再活跃的时候 比如 Activity 的 onresume onpause,才开是触发
- 每当 setValue 的时候 都会 把LiveData的 version +1,当Activity 不活跃的时候 ,不会触发,只有再活跃的是后续,才会触发,他的驱动 可以是认为 Activity 生命周期的驱动
三 使用
创建 LiveData 实例以存储某种类型的数据。这通常在 ViewModel 类中完成。在Activity 或者 Fragment中添加观察者,通常我们使用的是LiveData的一个子类 MutableLiveData,LiveData主要是用来存储不可变的对象,MutableLiveData是可以存储随时变化的类,在ViewModel中主要使用 MutableLiveData,观察者模式我上个文章已经写过简单例子了可以去看一下()
简单写一个计数器
先写一个ViewModel
class TimeViewModel : ViewModel() {
var time = 0
val timeMutableLiveData: MutableLiveData<Int> by lazy {
time = 0
getTime()
MutableLiveData<Int>()
}
private fun getTime() {
// 启动协程 延时1s 更改数据
viewModelScope.launch {
delay(1000)
timeMutableLiveData.value = ++time
getTime()
}
}
}
Activity中使用,observe 方法来观察数据 , observe 方法会察觉Activity的生命周期,observeForever 在 Activity不活跃的状态也会去通知观察者。但是系统不会主动remove此观察者,需要我们手动去removeObserver
class LiveDataActivity : AppCompatActivity() {
// 赖加载 ViewModel
private val viewModel: TimeViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
var binding = DataBindingUtil.setContentView<ActivityLivedataBinding>(
this,
R.layout.activity_livedata
)
// 开始观察数据
viewModel.timeMutableLiveData.observe(this, Observer {
tv_time.text = "${it}秒"
})
}
四 源码解析
4.1 observe 方法
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
// 先判断是不是主线程,如果不是主线程直接抛 异常
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// 如果 LifecycleOwner 的是生命周期已经处于 onDestroye的时候,直接return
return;
}
// LifecycleBoundObserver 是一个包装类,包装着LifecycleOwner和Observer
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
// mObservers 是存储 observer 和 wrapper的一个类,类似于HashMap,observer当做key ,wrapper当做value
// 存起来,如果以前存过这个wrapper,就返回以前的wrapper
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
// 被观察者不能观察一个Actitiy或者Fragment多次,否则直接抛异常
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
// 如果存在过,就不会再添加到观察者中
if (existing != null) {
return;
}
// 添加 Activity 或者 Fragment的生命周期观察者,当生命周期改变的时候 会调用 LifecycleBoundObserver 的 onStateChanged方法
owner.getLifecycle().addObserver(wrapper);
}
然后我们再看一下 LifecycleBoundObserver 类 和 他的父类 ObserverWrapper , 这两个都是LiveData的内部类
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
// 当 LifecycleOwner 处于 STARTED 和 RESUME的时候,返回true
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
// 当 LifecycleOwner (Activity 或者 Fragment)的生命周期发生变化的时候调用
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
// 再次判断 LifecycleOwner 是否已经desroy 。如果销毁 直接移除观察者
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
// 调用父类的方法
activeStateChanged(shouldBeActive());
}
// 判断是否已经添加过 LifecycleOwner
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
//移除此LifecycleOwner生命周期的观察者
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
然后再看看他的父类 ObserverWrapper
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
//
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<? super T> observer) {
mObserver = observer;
}
abstract boolean shouldBeActive();
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
void detachObserver() {
}
// 用着来判断是否是可接受的状态
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
mActive = newActive;
// 用 mActiveCount 计数相加法来判断 活跃的个数
boolean wasInactive = LiveData.this.mActiveCount == 0;
LiveData.this.mActiveCount += mActive ? 1 : -1;
if (wasInactive && mActive) {
// 当有活跃的时候 走这里 onActive 是 LiveData的方法,
onActive();
}
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive();
}
// 这个是当Activity从stop再次回到start时候会走到这里
if (mActive) {
dispatchingValue(this);
}
}
}
然后我们再看一下 LiveData 的 dispatchingValue 方法,用来 分发value
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
// 如果传过来的不是null,直接通知观察者,改变数据
considerNotify(initiator);
initiator = null;
} else {
// 当传过来是null的时候,直接去更新下面的数据 considerNotify
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
// 去通知观察者,改变数据
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
然后我们在看一下通知观察者的方法 considerNotify
@SuppressWarnings("unchecked")
private void considerNotify(ObserverWrapper observer) {
// 如果observer处于非活跃状态 直接return
if (!observer.mActive) {
return;
}
// 如果 不处于 ONSTART 或者 ONRESUME 继续走 ObserverWrapper的 activeStateChanged方法。
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
// 用来记录通知的版本,如果通知过了,就不用再通知了,很明显的一个例子,在onStart()已经通知了,在onResume就不会再通知了,
//每一个新注册的观察者,其version都为-1,所以当已经更改过的LiveData,当有一个新的观察者的时候,会直接拿到最新的 数据
if (observer.mLastVersion >= mVersion) {
return;
}
// 记录此次的 version
observer.mLastVersion = mVersion;
// 通知观察者
observer.mObserver.onChanged((T) mData);
}
4.2 setValue(T value) 方法
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
// 上面有这个方法的作用
dispatchingValue(null);
}
4.3 postValue(T value) 方法,在子线程中该数据
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
// 启动一个线程池,直接post到主线程
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
用LiveData 做两个例子 一个是 实现EventBus功能,另一个是6.0运行时权限demo