LiveData学习使用
记录一个在使用LiveData是遇到的有趣问题。由这个问题我们知道,在Activity中设置LiveData的Observer的时候,需要在onCreate中去设置。
起初些demo。主要是为了验证在SecondActivity,改变LiveData的值的时候,MainActivity的Observer何时被回调。
MainActivity代码
SecondActivity的代码
功能其实非常简单,定义一个单例的LiveData对象,然后在SecondActivity中改变LiveData的值,看MainActivity中的Observer是否会回调。
结论是再没有回到MainActivity的时候自然不会被回调,这个是符合预期的。
但是有一点我呢提,我发现回到MainActivity之后,居然执行了两次回调。日志如下。
怎么回事呢,看了一下,我设置监听是在onResume中,再次回到Main的时候又会设置一次监听,但是值已经变化了啊,为什么还会被回调呢。那肯定就是在添加observer的时候还有些判断,可以直接触发回调。看下LiveData的observer源码。
那就应该是标红的这一行中有触发回调的逻辑了。进到方法看一下。实际实现是在LifecycleRegistry.java中,代码如下
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
// 判断这个observer对象是否已经被添加过了,所以如果不想重复触发可以讲传入的observer设为成员变量,后面讲一下
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
if (previous != null) {
return;
}
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
// it is null we should be destroyed. Fallback quickly
return;
}
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
// ** 重点就在于这个state的计算 ,下一段代码就关于state的计算**
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
popParentState();
// mState / subling may have been changed recalculate
targetState = calculateTargetState(observer);
}
if (!isReentrance) {
// we do sync only on the top level.
sync();
}
mAddingObserverCounter--;
}
private State calculateTargetState(LifecycleObserver observer) {
Entry<LifecycleObserver, ObserverWithState> previous = mObserverMap.ceil(observer);
State siblingState = previous != null ? previous.getValue().mState : null;
State parentState = !mParentStates.isEmpty() ? mParentStates.get(mParentStates.size() - 1)
: null;
return min(min(mState, siblingState), parentState);
}
按照现在的这种讲Observer注册写道onResume中,LiveData被改变一次,只要Main没有被Destroy,每次进入Main页面都要走一次回调,这肯定是不行的。
根据源码展示,有两种方法,一种是在onCreate中注册,其实这本就是标准用法。另一种方法是将observer对象设置为成员变量(这一点我们可以从源码中看到)。具体方法可以自己看看。
今天还看了一下Jetpack中的Room,结合LiveData使用,简直是无敌了。过几天也写一下自己的理解。
总结
最近一直在找工作,因为感觉在OPPO继续呆着,做的业务也没啥意思了,很想做新模块的开发,可是连续面了五家,全部倒再一面,我还是两年前第一次找工作那样,什么问题我都能回答一些,但是往深了问就不知道了。两年前凭借面试表现,怎么面试都能拿下offer,因为当时作为一个工作一年的人来说我所掌握的知识的广度和深度,的确是比大部分人优秀的。但是现在我已经是一个工作三年的人了,对于基础知识的深度还是和以前一样,广度甚至变小了。在OPPO一直是埋头干事情,对现有模块添加一点东西,或者解决一些繁琐的业务bug。不涉及架构设计能力的提升,也不用学习任何的新东西,我就完全能够应付现有的工作需要。并且19年一整年,都是十点半以后下班的节奏,整个人都是非常疲惫的,接着就是完全忽略了对新技术的学习。也不再关注行业动态了。起先我一直都在埋怨OPPO这种没有技术氛围的工作环境,但是现在我才逐渐意识到,其实这些环境是一小部分因素,重点还是自己怎么做。我的室友,作为一名产品经理,每天比我回来的还晚,但是19年他看了大概有将近二十本书,并且大多数时候都是七点起床去健身。时间是靠自己争取的,知识也是靠自己汲取的。所以我觉得我需要重新开始好好学习一些非常好的东西。并且好好复习基础知识,即使我还是没办法找到心仪的工作,即使我可能还要继续留在OPPO,但是我一定会成为更优秀的人,我要为自己正名。