JetPack之LiveData2.2.0源码分析
基于:
api "androidx.lifecycle:lifecycle-extensions:2.2.0"
api "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
1. 为LiveData添加观察者observe
//liveData添加观察者observe viewModel.liveData.observe(this, Observer { }) public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) { assertMainThread("observe"); if (owner.getLifecycle().getCurrentState() == DESTROYED) { // 如果LifecycleOwner处于onDestroy状态就不处理 return; } //进行一层包装,使得观察者observer可以感知到activity的生命周期发生变化 LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer); ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper); if (existing != null && !existing.isAttachedTo(owner)) { //liveData不能添加具有不同生命周期的同一观察者 throw new IllegalArgumentException("Cannot add the same observer" + " with different lifecycles"); } if (existing != null) { return; } //注意:当添加wrapper后,马上就会执行LifecycleBoundObserver的onStateChanged()方法 owner.getLifecycle().addObserver(wrapper); }
1.1 LifecycleBoundObserver分析
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver { @NonNull final LifecycleOwner mOwner; LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) { super(observer); mOwner = owner; } @Override boolean shouldBeActive() { //判断activity是否处于活跃状态:当前状态是否大于等于STARTED, 满足条件的只有STARTED与RESUMED //也就是当activity处于onStart、onResume、onPause的时候,是活跃状态 return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED); } @Override public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) { // 由于实现了LifecycleEventObserver,当activity生命周期发生改变,到onDestroy后,就自动进行了移除 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); } }
然后就来到了activeStateChanged(shouldBeActive());
void activeStateChanged(boolean newActive) { if (newActive == mActive) { return; //活跃性状态一致 被return } mActive = newActive; boolean wasInactive = LiveData.this.mActiveCount == 0; LiveData.this.mActiveCount += mActive ? 1 : -1; if (wasInactive && mActive) { onActive();//当liveData的活动观察者的数量从0变为1时调用。 } //注意:一个liveData可以添加多个观察者,所以每个观察者都对应一个该方法,但是LiveData.this.mActiveCount是公共的 if (LiveData.this.mActiveCount == 0 && !mActive) { onInactive();//当liveData的活动观察者的数量从1变为0时调用。 } if (mActive) { dispatchingValue(this); //只有mActive为true 并且newActive为false的时候才能走入这里 ,也就是从非活跃状态到活跃状态 } } //接着看事件分发 void dispatchingValue(@Nullable ObserverWrapper initiator) { //防止重复分发相同的内容 if (mDispatchingValue) { mDispatchInvalidated = true; return; } mDispatchingValue = true;//开始发送事件 赋值为true do { mDispatchInvalidated = false; if (initiator != null) { //只处理当前Observer,因为每个Observer 都会单独走一遍dispatchingValue方法 considerNotify(initiator); initiator = null; } else { //当使用setValue的时候, initiator为null。 遍历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;//发送完毕后,还原 } private void considerNotify(ObserverWrapper observer) { if (!observer.mActive) { return; } if (!observer.shouldBeActive()) { observer.activeStateChanged(false); return; } if (observer.mLastVersion >= mVersion) { return; } observer.mLastVersion = mVersion; observer.mObserver.onChanged((T) mData);//数据回调到观察者 }
2. 版本号mVersion的作用:
当把LifecycleBoundObserver添加到LifecycleOwner后,会马上执行LifecycleBoundObserver的onStateChanged()方法,使得跟activity的生命周期状态同步,
接着也就会执行activeStateChanged() -> dispatchingValue() -> considerNotify() 但此时observer.mLastVersion不会大于mVersion,所以被mVersion拦截,就不会执行onChanged()方法了
3. LiveData数据覆盖问题
protected void setValue(T value) { assertMainThread("setValue"); mVersion++; mData = value; dispatchingValue(null); }
当activity不在活跃状态时,多次调用liveData.setValue方法,会被observer.shouldBeActive()拦截,而mData会等于最后一次setValue的值,当activity由非活跃变成活跃状态后,会走到LifecycleBoundObserver -> onStateChanged -> activeStateChanged -> dispatchingValue ,再将mData回调出去,也就是只有最后一次setValue的值被观察者拿到了。
对于postValue
protected void postValue(T value) { boolean postTask; synchronized (mDataLock) { postTask = mPendingData == NOT_SET; mPendingData = value; //保存需要发送的值 } if (!postTask) { return; //如果mPostValueRunnable没走完,后面再调用postValue,在这里进行拦截,而mPendingData记录的最后一次的数据 } //需要经过handler进行一次线程的切换,然后再调用setValue。(这里就要看handler的post执行原理了) ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable); }
现象如下:
//在点击事件中执行下面方法(此时activity是活跃状态) btn.setOnClickListener { viewModel.liveDataTest() } viewModel.liveData.observe(this, Observer { Log.e("tag", " it = $it") }) fun liveDataTest() { viewModelScope.launch { withContext(Dispatchers.IO) { liveData.postValue("post的数据1") liveData.postValue("post的数据2") liveData.postValue("post的数据3") } } liveData.setValue("set的数据1") liveData.setValue("set的数据2") } //输出日志: it = set的数据1 it = set的数据2 it = post的数据3
4. 使用observeForever()的方式添加观察者,避免发送的data被覆盖
//使用observeForever的方式添加观察者时,内部的包装内为AlwaysActiveObserver viewModel.liveData.observeForever { } private class AlwaysActiveObserver extends ObserverWrapper { AlwaysActiveObserver(Observer<? super T> observer) { super(observer); } @Override boolean shouldBeActive() { //LifecycleBoundObserver的shouldBeActive受activity的状态影响,这里直接返回true,也就不管activity处于什么状态,都会发送data了 return true; } }
由于使用了observeForever后,AlwaysActiveObserver不能感知activity的生命周期,也就不能像LifecycleBoundObserver一样帮我们removeObserver()了,所以需要我们自己手动调用removeObserver()方法去解除绑定
LiveData源码总结
- LiveData的观察者可以联动生命周期, 也可以不联动。在联动生命周期时,会自动在 DESTROYED 的状态下移除 Observer ,取消订阅,所以不用担心内存泄露;
- LiveData的观察者只能与一个LifecycleOwner绑定, 否则会抛出异常。而一个 owner 可以绑定多个 Observer 实例;
- LiveData 跟 LifecycleOwner 绑定,能感知生命周期变化,并且只会在 LifecycleOwner 处于 Active 状态(STARTED/RESUMED)下通知数据改变;如果数据改变发生在非 active 状态,数据会变化,但是不发送通知,等 owner 回到 active 的状态下,再发送通知;
- 使用observeForever()方法,会注意AlwaysActiveObserver对象,意味着给定的观察者将接收所有事件,并且永远不会被自动删除,不管在什么状态下都能接收到数据的更改通知
- LiveData 利用版本管理、绑定 Lifecycle 确保了只会发送最新的数据给 active 状态下的 Observer