- 本篇笔记主要是记录Livedata的原理和源码分析。
一.简介
-
Livedata是一个可观察的数据持有者,与常规observable不同,LiveData是生命周期感知的。
-
补充一下接口和观察者的区别:本质上没什么区别,只不过接口是1对1,观察者是不单单只是1对1;
二.基本使用
public class MainActivity extends AppCompatActivity {
private static final String TAG="MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//创建对象
MutableLiveData<String> mutableLiveData = new MutableLiveData<>();
//设置监听
mutableLiveData.observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable final String s) {
Log.d(TAG, "触发onChanged:" + s);
}
});
//发生数据
mutableLiveData.postValue("发送数据");
}
}
- 注意:设置监听和发送数据的步骤是不分先后顺序的,至于原因,了解源码后就会明白。
- 本篇笔记的重点是源码分析和实现原理,基本用法就略写了。
三.源码分析
- 源码从监听方法开始或者从发送数据方法开始都可以,只不过内部代码的执行流程会有点不同,我们选取一个方向即可。先从设置监听方法开始。
- 提示:在分析Livedata源码之前,请先去分析一下Lifecycle的源码。因为涉及到的Lifecyle源码相关已经写过一篇笔记,这里涉及到Lifecycle的情况下,只会提及一下思想,不涉及具体细节。
3.1.分析设置监听的方法
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
//1.判断组件的生命周期是否结束了
//这里我们看到了Lifecycle的影子,下方也有
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
return;
}
//2.把组件和观察者都封装到了LifecycleBoundObserver(非常重要)
//参数1:组件
//参数2:观察者
//在3.2中分析LifecycleBoundObserver
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
//3.每当添加一个观察者,会把观察者添加到map集合中(此时,mObservers就有值了)
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
//...
//决定生命周期的感知(非常重要)
//4.给组件的生命周期添加了一个观察者(即Livedata内部使用了Lifecycle)
owner.getLifecycle().addObserver(wrapper);
}
3.2.LifecycleBoundObserver
-
在分析该类之前,我们先回顾一个Lifecycle的原理,根据owner.getLifecycle().addObserver(wrapper)可以知道,最终会执行ObserverWrapper的onStateChanged方法,而ObserverWrapper是抽象类,故执行其子类的onStateChanged方法。那onStateChanged被调用的时机是什么时候呢?同样的跟Lifecyle一样,被观察者的生命周期方法调用后就会触发onStateChanged方法。
-
当postvalue的时候做的事情实际上就是一件,将value存储到mdata中并mVersion++。然后目标的activity的生命周期方法被触发的时候就会调用 ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event)方法,最终是调用mLifecycleObserver.onStateChanged(owner, event)的方法,最终是调用Livedata中的LifecycleBoundObserver类onStateChanged方法。
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() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
//DESTROYED状态,回收观察者
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
//6.调用activeStateChanged方法(被观察者生命周期方法调用时,触发该方法)
//在3.3中分析activeStateChanged
//shouldBeActive:被观察者的是否处于可见状态
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
3.3.分析activeStateChanged
private abstract class ObserverWrapper {
final Observer<? super T> mObserver; //观察者(在3.2中已经被赋值)
boolean mActive;
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<? super T> observer) {
mObserver = observer;
}
abstract boolean shouldBeActive();
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
void detachObserver() {
}
//6.1.当activity生命周期改变的时候,就会回调该方法(需要先了解Lifecyle的原理)
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
//onCreate执行的时候mActive = false
//执行了onStart或者onResume方法时候mActive = true
mActive = newActive;
boolean wasInactive = LiveData.this.mActiveCount == 0;
LiveData.this.mActiveCount += mActive ? 1 : -1;
if (wasInactive && mActive) {
onActive(); //空实现
}
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive(); //空实现
}
//12.activity的onStart方法调用了,进入if语句
//6.2.如果被观察者是处于活动状态(activity执行了onStart或者onResume方法),才进入if语句
if (mActive) {
//7.调用dispatchingValue,在3.4中分析
dispatchingValue(this);
}
}
}
3.4分析dispatchingValue
- dispatchingValue内部的一些boolean变量是防止Livedata递归调用时做的容错处理(知道即可,源码分析完之后可以自行模拟一下)
- 当先发送数据,再设置监听,该方法的执行流程会不同。另外,重复设置监听,该方法的执行流程又会不同。我们先知道这些即可,先按照笔记的思路分析源码,再回头自行捋一遍相信会比较清楚。
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
//initiator不为null
if (initiator != null) {
//8.在3.5中分析considerNotify
considerNotify(initiator); //12.1继续执行
initiator = null;
} else {
//11.1.集合中有数据,故会执行for循环,这里会执行一次considerNotify(执行次数由集合的长度决定)
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
//11.2.发送数据是activity的onCreate方法中调用的,故执行的结果跟3.5一样。
//此时,就有问题了,监听设置了,数据也发送了,回调方法没执行,不着急。我们在3.5中分析
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
3.5分析considerNotify
private void considerNotify(ObserverWrapper observer) {
//11.3.再次回到该方法
//9.验证UI是否显示
//根据6.2可以知道,activity只调用onCreate方法,但是还未调用onStart或者onResume方法,是不会执行到这里来的
//而当调用onStart或者onResume方法!observer.mActive = false
//问题:如果我们在activity的其它生命周期方法中设置监听,而且还设置多次,那么源码的执行逻辑是如何的?当我们按照笔记的思路去把源码分析一边,再来思考这个问题,应该也不难的。先有印象,我们现在该去分析发送数据的方法的源码了
//11.4.若setValue是在onCreate方法设置,则进入,若在onStart或者onResume方法执行则相反
//我们这里就按照二中的写法来分析,那么当activity的onCreate方法执行完后到此就结束了。
//那么回调没有得到onChanged触发,下面该如何分析?
//当onCreate方法执行完,activity在执行onStart方法时,又会触发步骤6中的方法,回到步骤6继续分析
//12.2.不进入
if (!observer.mActive) {
return;
}
//被观察者是否处于非活动状态
//12.3.不进入
if (!observer.shouldBeActive()) { //11.5.同11.4
observer.activeStateChanged(false);
return;
}
//在还未调用postValue方法之前,mLastVersion的值为-1,mVersion的值也为-1
//mLastVersion的赋值时机是LifecycleBoundObserver被创建的时候
//mVersion的赋值时机是在activeStateChanged方法被调用的时候
//也就是说,只设置监听,不管实在activity的onCreate还是onStart或onResume中设置,都会进入if语句
//即不触发onChanged回调
//12.4.此时不进入(mLastVersion = -1,mVersion = 0)
if (observer.mLastVersion >= mVersion) {
return;
}
//12.5.mLastVersion = mVersion = 0
observer.mLastVersion = mVersion;
//12.6.触发回调 回到3.7中
observer.mObserver.onChanged((T) mData);
}
3.6.分析setValue
- 先补充一点,setValue和postValue区别:
- setValue 只能在子线程上运行,postValue 可以在任意线程上运行(底层使用到了handler,postValue 最终还是调用的是setValue );
//该成员变量是正在的数据持有者
private volatile Object mData;
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
//10.mVersion + 1 设置一次的情况mVersion = 0
mVersion++;
//10.1.存储到成员变量中
mData = value;
//11.分析dispatchingValue,回到3.4中看对应步骤的注释
dispatchingValue(null);
}
3.7.总结
-
源码分析的流程跟被观察者的生命周期方法执行关联性很强,关于activity的onResume的方法被调用后,代码的执行流程,可以按照上面的同样的方式进行分析。
-
另外,监听设置多次,已经在不同被观察者不同的生命周期方法中设置,如果把Lifecycle的笔记和上面的笔记梳理清楚了,其源码的执行流程的分析我觉得也不难了。有兴趣大家可以自行研究。
评论区