这是我参与更文挑战的第17天,活动详情查看: 更文挑战markdown
附上一篇Livedata使用篇app
Livedata使用篇ide
不太擅长画图,勉强画了一幅源码分析
若是您对Livedata的源码有必定了解看了这个图应该就差很少了。post
若是对Livedata源码了解很少,那么粗略看一下图,而后直接看后面的逻辑。看完逻辑回过头再细看时序图效果更佳学习
既然是源码解析,天然入口就是咱们的方法调用,这里简单把注册 Livedata 的数据监听和 Livedata.setValue 方法进行简单说明this
mapViewModel.mapLiveData.observe(this,{//这个回调中会收到数据更改的监听
logEE(it)
tv_map.text=it
})
复制代码
val userLivedata =MutableLiveData<User>()
fun sendData() {
userLivedata.value=User("李白",1200)//这句代码发送最新数据
}
复制代码
下一节就是 Livedata 的工做流程简单分析了spa
我主要把代码逻辑分为了三部分:线程
业务代码 Livedata.observe 注册数据观察code
setValue 发送最新数据
用户视图回到前台自动进行数据分发
第一部分逻辑:
基本的逻辑就是咱们注册数据监听的时候,会传入一个 LifeCycle 的数据监听者接口。Livedata 的 observe 方法会将接口封装成一个 LifecycleBoundObserver对象,而且注册 LifeCycle 的生命周期监听。
第二部分逻辑:
当咱们调用 Livedata.setValue 方法的时候,会逐个遍历每个注册的 LifecycleBoundObserver,而后分别调用 Observer 的 onChange 回调方法向咱们的业务数据监听返回数据
第三部分逻辑:
由于咱们注册了 LifeCycle 的生命周期,当用户视图回到前台的时候会回调 LifecycleBoundObserver 的 onStateChanged 方法。onStateChanged 方法内会进行数据的分发
本节讲了 Livedata 的基本逻辑,下一节主角就是代码了
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {//若是生命周期已经被销毁,return。这说明了使用Livedata不会发生内存泄露的缘由
// ignore
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);//这个对象是LifecycleEventObserver的一个实现,是咱们注册生命周期组件的观察者
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);//将wrapper加入到map中,获得上一个wrapper,
if (existing != null && !existing.isAttachedTo(owner)) {//isAttachedTo:上一个wrapper关联的生命周期若是不是当前生命周期,就抛出异常
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {若是上一个wrapper不为空就return(由于会复用上一个wrapper)
return;
}
owner.getLifecycle().addObserver(wrapper);//若是上一个为空则说明是第一次,须要注册生命周期监听
}
复制代码
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;//数据的版本,每次调用setValue都会++
mData = value;
dispatchingValue(null);//分发数据
}
复制代码
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {// 一、若是正在分发中则返回
mDispatchInvalidated = true;// 二、目的是若是有新的setValue方法被调用,会在步骤4中跳出for循环,从新再进行一次分发
return;
}
mDispatchingValue = true;、// 三、设置正在分发中状态为true,防止1中重复进入分发消息
do {
mDispatchInvalidated = false;// 四、进入循环后设置mDispatchInvalidated为false,若是用户从新setValue须要将mDispatchInvalidated从新设置为true,一边能够在上一轮分发结束后继续走一轮分发
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) {//六、若是这里为true说明用户又设置了一次value,那么跳出for循环,从新执行外层的dowhile循环
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;//七、消息分发完成,设置正在分发中状态为false
}
复制代码
3.经过分析,咱们发现 dispatchingValue 方法内最终再次分发消息的方法是 considerNotify,方法体:
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {//一、若是当前lifecycle不是活跃状态就返回不进行消息分发,销毁会在生命周期最近变活跃的时候自动分发
return;
}
if (!observer.shouldBeActive()) {//二、若是lifecycle状态为started||resumed
observer.activeStateChanged(false);//三、激活状态,activeStateChanged方法里面会再次调用dispatchValue分发消息,通常用做livedata从不活跃状态回到活跃状态的时候自动分发消息
return;
}
if (observer.mLastVersion >= mVersion) {//四、若是true,说明第6步中有更小版本的消息正在调用,因此返回
return;
}
observer.mLastVersion = mVersion;//五、记住当前正在分发value的版本,用于第四部中的逻辑判断
observer.mObserver.onChanged((T) mData);//六、调用注册livedata的observer的onChanged通知用户更新数据
}
复制代码
considerNotify 方法中调用了 mObserver.onChanged 后就会回调咱们业务代码中的消息注册监听,整个数据流转的逻辑就完成了
逻辑同 Livedata.setValue
咱们知道咱们是经过 LifeCycle 生命周期组件来监听生命周期的。
监听生命周期的接口实现就是 LifecycleBoundObserver 类,当生命周期发生改变的时候会回调 LifecycleBoundObserver 类的方法 onStateChanged:
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();//重置生命周期状态
}
}
复制代码
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
mActive = newActive;
changeActiveCounter(mActive ? 1 : -1);
if (mActive) {
dispatchingValue(this);//看到这里你直接去找上一节Livedata.setValue的源码分析就ok了
}
}
复制代码
实际没啥好说的,就是将线程切回到主线程,而后调用 Livedata.setValue 更新数据而已。
最后,更重要的在下面:
关注个人公众号 “安安安安卓” 学习更多知识