LiveData特性:
1、只有在活跃状态(STARTED,RESUMED)才会收到通知,非活跃状态不会收到更新通知。
2、只有在数据发生变化时才发生更新,且只发送给处于活跃状态的观察者。
3、观察者在首次从非活跃状态变为活跃状态时,会收到更新通知。若第二次从非活跃状态转为活跃状态,则只在值变化时,才会收到通知。
使用注意:
1、尽量放在ViewModel中,不放在Activity或Fragment中,原因:其一、避免Activity/Fragment冗余;其二、在Activity/Fragment配置更改后继续存在。
2、onCreate方法是开始观察LiveData对象的正确着手点。(onCreate方法调用时,Activity/Fragment正处于INITIALIZED状态)
LiveData类图:
从图中可以看出LiveData以一个Map来保存Observer,并且用ObserverWrapper对Observer进行了封装。封装的目的是为了获取“组件状态”,只通知处于活跃状态的观察者。
接下来,以一个介绍LiveData运作过程。包含:一、添加观察者;二、数据发生变化,给观察者发送更新通知;三、生命周期状态发生变化,发送更新通知;四、生命周期结束,撤销观察者。
LiveData执行过程:
通常可能的LiveData用法如下:
searchPageViewModel.hintWordDataList.observe(viewLifecycleOwner, Observer {
adapter.dataList = it
adapter.notifyDataSetChanged()
})
一、添加观察者:
上面的observe方法的实现如下:
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// 如果Activity或Fragment处于DESTROYED状态,就不需要设置观察者了
return;
}
//封装Observer和LifecycleOwner到wrapper中,以实现只通知活跃状态的Observer的目的
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
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;
}
//添加一个生命周期的观察者,以在生命感知组件变为活跃状态时,发生更新通知
owner.getLifecycle().addObserver(wrapper);
}
在添加LiveData的观察者时,首先将LifecycleOwner和Observer封装到了LifecycleBoundObserver中,此类的作用是:一、提供Observer的状态(即生命感知组件的状态),以实现只通知活跃状态Observer的目的。二、实现了LifecycleEventObserver接口,以观察生命感知组件(Activity或Fragment)的状态变化,在生命感知组件变为活跃状态时,给LiveData的观察者发送一个更新通知。然后,将LifecycleBoundObserver作为“value”,添加到了一个以Observer为“key”的Map中。
二、数据发生变化,给观察者发送更新通知
通常,LiveData会调用setValue方法更新值,其代码如下:
protected void setValue(T value) {
assertMainThread("setValue");
//mVersion表示“值”的版本,每更新一次就加1
mVersion++;
mData = value;
dispatchingValue(null);
}
接下来,会调用dispatchingValue方法,以通知观察者值发生变化,注意这里的参数值为null,此方法代码如下:
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
//正在通知观察者,则直接返回,不重复执行相同的操作
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
//通知指定观察者initiator,LiveData的值发生变化
considerNotify(initiator);
initiator = null;
} else {
//通知所有观察者,LiveData的值发生变化
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
此方法的形参为initiator,若initiator不为null,则只对initiator指定的观察者发送更新通知;若为null,则对所有注册的观察者都发送更新通知。在此会调用considerNotify发送更新通知,此方法代码如下:
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
// 检查是否处于活跃状态(STARTED或RESUMED)
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
// 检查是否处理过LiveData的最新值
if (observer.mLastVersion >= mVersion) {
return;
}
// 未处理过LiveData的最新值,进行处理:
// 更新mLastVersion并调用Observer的onChanged方法
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
}
三、生命周期状态发生变化,发送更新通知
前面提过的LifecycleBoundObserver会实现LifecycleEventObserver接口,以观察生命感知组件的状态。此类代码如下:
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
//检查Lifecycle(Activity/Fragment)是否处于活跃状态
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
//获取Lifecycle的状态
Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
if (currentState == DESTROYED) {
removeObserver(mObserver);
return;
}
Lifecycle.State prevState = null;
while (prevState != currentState) {
prevState = currentState;
//通知观察者Observer 状态发生变化
// 若状态为STARTED或RESUMED,则shouldBeActive()为true
activeStateChanged(shouldBeActive());
currentState = mOwner.getLifecycle().getCurrentState();
}
}
......
}
在生命感知组件的状态变化时,会调用onStateChanged方法,在此方法中,会检查是否处于活跃状态,若处于活跃状态,会调用activeStateChanged通知观察者Observer,状态发生变化,此方法代码如下:
void activeStateChanged(boolean newActive) {
//若处于活跃状态,newActive为true
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
// 告知LiveData,使mActiveCount值加1或减1
// mActiveCount表示处于活跃状态的观察者的数量
changeActiveCounter(mActive ? 1 : -1);
if (mActive) {
//给当前观察者发送更新通知
//观察者不一定会更新,由观察者的mLastVersion与LiveData的mVersion决定
dispatchingValue(this);
}
}
四、生命周期结束,撤销观察者
当Activity/Fragment处于DESTROYED状态时,LifecycleBoundObserver会收到通知,并撤销LiveData的观察者,代码如下:
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
//获取Lifecycle的状态
Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
if (currentState == DESTROYED) {
//撤销LiveData的观察者
removeObserver(mObserver);
return;
}
Lifecycle.State prevState = null;
while (prevState != currentState) {
prevState = currentState;
//通知观察者Observer 状态发生变化
// 若状态为STARTED或RESUMED,则shouldBeActive()为true
activeStateChanged(shouldBeActive());
currentState = mOwner.getLifecycle().getCurrentState();
}
}
此方法会调用removeObserver方法,代码如下:
public void removeObserver(@NonNull final Observer<? super T> observer) {
assertMainThread("removeObserver");
//从LiveData的Map中移除观察者
ObserverWrapper removed = mObservers.remove(observer);
if (removed == null) {
return;
}
//最后一次通知观察者,其被移除
removed.detachObserver();
removed.activeStateChanged(false);
}
在此方法中,会调用detachObserver方法告知观察者,其被移除,以使观察者做一些移除后的操作,代码如下:
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
这里,在观察者被移除之后,也就不需要观察生命感知组件(Activity或Fragment)的状态变化了,所以要移除之前对生命感知组件添加的观察者。
至此,LiveData的执行过程就分析结束了。