1、只有在活跃状态(STARTED,RESUMED)才会收到通知,非活跃状态不会收到更新通知。
2、只有在数据发生变化时才发生更新,且只发送给处于活跃状态的观察者。
3、观察者在首次从非活跃状态变为活跃状态时,会收到更新通知。若第二次从非活跃状态转为活跃状态,则只在值变化时,才会收到通知。
1、尽量放在ViewModel中,不放在Activity或Fragment中,原因:其一、避免Activity/Fragment冗余;其二、在Activity/Fragment配置更改后继续存在。
2、onCreate方法是开始观察LiveData对象的正确着手点。(onCreate方法调用时,Activity/Fragment正处于INITIALIZED状态)
从图中可以看出LiveData以一个Map来保存Observer,并且用ObserverWrapper对Observer进行了封装。封装的目的是为了获取“组件状态”,只通知处于活跃状态的观察者。
接下来,以一个介绍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的执行过程就分析结束了。