前言
在一通研究下,我打算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的源码:
@MainThread
protected 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:
@Nullable
public T getValue() {
Object data = mData;
if (data != NOT_SET) {
return (T) data;
}
return null;
}
好像就是一个获取data值的操作 😶
observer:
接下来是重头戏了,看看observer是怎么实现数据更新他就知道的:
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
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
// owner
mActive = newActive;
changeActiveCounter(mActive ? 1 : -1);
if (mActive) {
dispatchingValue(this);
}
}
}
在里面有几个关键的成员属性:mActive和mLastVersion 。虽然只有一个avtivaStateChanged的方法,但是通过这个方法我们就能管中窥豹——LiveData在程序活跃的时候才会进行数据的观察和修改。
接下来我们再看LifecycleBoundObserver,Lifecycle也是老演员了,我们来看看这个Owner是怎么个事:
Override
public 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的生命周期改变了。
好了,大概就这么多
求关注
感觉主包讲的还可以可以给个关注😋