LiveData是Android提供的监听数据更新的框架,它能够感应Activity/Fragment的生命周期,接下来的内容我们来通过简单的用法去探索LiveData源码的核心知识点。
Android涉及到生命周期的时候,基本都是和Lifecycle类有关,我们先来看一下
**LiveData.observe(LifecycleOwner owner, @NonNull Observer super T> observer)**里面的代码:
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer super T> observer) {
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
...
...
owner.getLifecycle().addObserver(wrapper);
}
Lifecycle是谷歌提供的用来监听Activity与Fragment的生命周期变化,Lifecycle提供了两个接口:
上面简单的讲解了Lifecycle的作用,回到上面那段代码,我们可以看到,当检测到当前是生命周期是DESTROYED的时候,直接忽略掉,不进行添加任何监听器。
接下来我们再看看LifecycleBoundObserver类:
class LifecycleBoundObserver extends ObserverWrapper
LifecycleBoundObserver类是ObserverWrapper抽象类的子类:
private abstract class ObserverWrapper {
....
// 是否激活状态
abstract boolean shouldBeActive();
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
//分离监听
void detachObserver() {
}
//激活状态改变
void activeStateChanged(boolean newActive) {
....
}
}
可以看到,ObserverWrapper抽象类主要是定义了一些固定的规范,然后我们看看LifecycleBoundObserver类的代码:
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer super T> observer) {
super(observer);
mOwner = owner;
}
@Override
boolean shouldBeActive() {
// 只有大于Start状态才是激活状态
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
// 当前是DESTROYED状态的时候直接不处理,并删除监听
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
//移除监听
mOwner.getLifecycle().removeObserver(this);
}
}
LifecycleBoundObserver是一个包装类,是对LifeCycleOwner和LifeCycleObserver的组合。
所以我们总结一下:
LiveData是通过Lifecycle来感应生命周期的,当Activity/Fragment在Start和Destory之间时,才会发送更新信息,否则不进行更新,想要更具体的理解这一块内容,还是得往下看。
LiveData用监听的处理分两种:
我们先来看看能够感应生命周期的代码段:
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer super T> observer) {
// 1.0检测当前是否是主线程
assertMainThread("observe");
// 2.0当前是DESTROYED状态,直接忽略
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
return;
}
// 3.0把生命周期拥有者和观察者包装起来
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
// 4.0 以Map的结构添加包装类,然后判断是否已经添加过了,已经添加则抛出异常
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
// 5.0将监听者添加到相应位置
owner.getLifecycle().addObserver(wrapper);
}
总结流程如下:
然后我们再看看不考虑感应生命周期的代码段:
public void observeForever(@NonNull Observer super T> observer) {
assertMainThread("observeForever");
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && existing instanceof LiveData.LifecycleBoundObserver) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
wrapper.activeStateChanged(true);
}
可以看到不考虑感应生命周期的时候,基本流程和感应生命周期的一致,只是使用了不同的ObserverWrapper抽象类的包装子类,我们来看看AlwaysActiveObserver的代码:
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer super T> observer) {
super(observer);
}
@Override
boolean shouldBeActive() {
return true;
}
}
从AlwaysActiveObserver类中的激活状态是永远返回True的,那么说明其永远都是激活态。
LiveData提供了两个方法进行更新数据:
我们先看看LiveData.postValue的代码:
protected void postValue(T value) {
boolean postTask;
1.0 加锁,并把value赋值给全局变量mPendingData
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
2.0 判断mPendingData是否已经完成之前的任务
if (!postTask) {
return;
}
3.0 切换到主线程执行任务
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
4.0 把mPendingData全局变量赋值给局部变量,然后把mPendingData恢复初始状态
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
5.0 设置更新值
setValue((T) newValue);
}
};
从上面的代码,我们可以总结出,LiveData.postValue主要是做了线程的切换工作,最终还是由LiveData.setValue来完成数据的更新提醒:
protected void setValue(T value) {
assertMainThread("setValue");
//版本+1
mVersion++;
// 全局变量保存需要更新的值
mData = value;
dispatchingValue(null);
}
void dispatchingValue(@Nullable ObserverWrapper initiator) {
...
do {
mDispatchInvalidated = false;
if (initiator != null) {
// 更新数据的通知
considerNotify(initiator);
initiator = null;
} else {
for (Iterator, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
...
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
private void considerNotify(ObserverWrapper observer) {
// 不是激活状态不处理
if (!observer.mActive) {
return;
}
// 判断是不处于激活状态
if (!observer.shouldBeActive()) {
// 通知激活状态改为false
observer.activeStateChanged(false);
return;
}
// 监听者的版本号大于当前的版本号不分发
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
// 通知数据的更新
observer.mObserver.onChanged((T) mData);
}
总结整个更新值通知的流程就是: