jetpack之LiveData的原理解析
前言
在一通研究下,我打算LiveData的解析通过从使用的方法上面切入进行LiveData的工作原理分析😋。感觉这样子更能让大家伙理解明白,LiveData的实现和Lifecycle分不开,并且还得需要知道LiveData的使用会用到什么样的方法。所以,还不了解这两者的朋友可以看一下我之前写的博客:
前置知识
jetpack之lifecycle的原理分析https://blog.csdn.net/i_xiang_la_shi/article/details/147191937?fromshare=blogdetail&sharetype=blogdetail&sharerId=147191937&sharerefer=PC&sharesource=i_xiang_la_shi&sharefrom=from_linkjetpack之LiveData的简单使用(特别简单,让你爽到飞!)
https://blog.csdn.net/i_xiang_la_shi/article/details/147309717?fromshare=blogdetail&sharetype=blogdetail&sharerId=147309717&sharerefer=PC&sharesource=i_xiang_la_shi&sharefrom=from_link
LiveData的几个方法:
setValue:
虽然kotlin在使用LiveData的时候看似是直接赋值,其实是调用了setValue的方法。我们先来看setValue的源码:
@MainThreadprotected void setValue(T value) {assertMainThread("setValue");mVersion++;mData = value;dispatchingValue(null);}
通过代码我们可以观察到一个MainThred的注解,这说明setValue是一定要运行在主线程上的(也就是UI线程)。
mVersion是决定此事件是否为粘性事件的关键,如果mVersion>mLastVersion,那么就不是粘性事件,直接进行分发。
mData也就是数据了。
dispatchingValue看名字像是分发值,进入此方法,我们能发现他进行了一个遍历:
@SuppressWarnings("WeakerAccess") /* synthetic access */void dispatchingValue(@Nullable ObserverWrapper initiator) {if (mDispatchingValue) {mDispatchInvalidated = true;return;}mDispatchingValue = true;do {mDispatchInvalidated = false;if (initiator != null) {considerNotify(initiator);initiator = null;} else {for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {considerNotify(iterator.next().getValue());if (mDispatchInvalidated) {break;}}}} while (mDispatchInvalidated);mDispatchingValue = false;}
dispatchingValue会遍历观察者列表,根据活跃状态和版本号决定是否分发数据(在considerNotify中有所体现)。
为什么我笃定它在setvalue中执行的时候就一定会遍历观察者列表呢?因为在setValue中他永远都发送的null,总会进入到else分支。
ObserverWrapper在后面的observe方法会简单讲一下
postValue:
接下来趁热打铁看一下postValue👌。
protected void postValue(T value) {boolean postTask;synchronized (mDataLock) {postTask = mPendingData == NOT_SET;mPendingData = value;}if (!postTask) {return;}ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);}
我们可以看到最后一行有一个postToMainThread的方法 。证明这个方法可以在子线程中运行,不过最终还是得去主线程。
点进这个Runnable参数看一下->
还是看最后一行:postValue最终还是通过setValue进行数据的修改。
所以,我们可以说,postValue通过 Handler
切换到主线程执行 setValue()
,支持子线程更新
getValue:
看完setValue接着我们来看看getValue:
@Nullablepublic T getValue() {Object data = mData;if (data != NOT_SET) {return (T) data;}return null;}
好像就是一个获取data值的操作 😶
observer:
接下来是重头戏了,看看observer是怎么实现数据更新他就知道的:
@MainThreadpublic void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {assertMainThread("observe");if (owner.getLifecycle().getCurrentState() == DESTROYED) {// ignorereturn;}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);}
一样是运行在主线程的(这不废话),毕竟不在主线程也感知不到生命周期的变化😄
我们先看老熟人——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;}// immediately set active state, so we'd never dispatch anything to inactive// ownermActive = newActive;changeActiveCounter(mActive ? 1 : -1);if (mActive) {dispatchingValue(this);}}}
在里面有几个关键的成员属性:mActive和mLastVersion 。虽然只有一个avtivaStateChanged的方法,但是通过这个方法我们就能管中窥豹——LiveData在程序活跃的时候才会进行数据的观察和修改。
接下来我们再看LifecycleBoundObserver,Lifecycle也是老演员了,我们来看看这个Owner是怎么个事:
Overridepublic void onStateChanged(@NonNull LifecycleOwner source,@NonNull Lifecycle.Event event) {Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();if (currentState == DESTROYED) {removeObserver(mObserver);return;}Lifecycle.State prevState = null;while (prevState != currentState) {prevState = currentState;activeStateChanged(shouldBeActive());currentState = mOwner.getLifecycle().getCurrentState();}}
源码太多,但是这个方法像是鹤立鸡群那只鹤有,直接被我捕获到了哈哈哈(事实是抱着侥幸的心理查找了一下changed😜)
LifecycleBoundObserver看来就是告诉livedataOwner的生命周期改变了。
好了,大概就这么多
求关注
感觉主包讲的还可以可以给个关注😋