Jetpack系列目录:
1、 Lifecycle原理分析
2、 LiveData原理分析
3、 DataBinding原理分析
4、 Navigation原理分析
1.LiveData的使用分析
可以看出 observe() 方法有两个参数:
1)第一个参数是LifecycleOwner
2)第二个参数是observer
MutableLiveData<String> liveData=new MutableLiveData<>();
// observe 订阅关系
liveData.observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
Log.e(TAG, "onChanged: "+s );
}
});
2.LiveData的核心原理
1)observe方法中主要是用 LifecycleBoundObserver 将LifecycleOwner进行一次包装后,存入 mObservers 的一个Map集合中,最后addObserver方法将 observer对象 和 owner对象 的生命周期进行绑定。
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
//根据 state 判断当前被观察者
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
......
owner.getLifecycle().addObserver(wrapper);
}
2)LifecycleBoundObserver封装类,实现了LifecycleEventObserver接口,LifecycleEventObserver的超类接口是LifecycleObserver,所以说LifecycleBoundObserver是一个观察者的封装类。
当 被观察者生命周期发生改变的时候会调用dispatch方法最终会调用到 mLifecycleObserver.onStateChanged(owner, event)(如果不清楚建议先去了解一下Lifecycle的原理),而LifecycleBoundObserver类中也实现了这个方法。
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
// 当LifecycleOwner生命周期发生变化时,调用这个函数
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();
}
}
这儿就会有removeObserver方法判断当关联的应用组件的状态变为 DESTROYED 时,移除此观察者避免内存泄露。(面试可能问)
同时还会有另一个方法 activeStateChanged(shouldBeActive()),如果shouldBeActive()返回true,则表示 compareTo(state) >= 0当前的被观察者的生命周期状态已经是可见状态了,将会执行到dispatchingValue方法中去。
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;
}
这个方法有两次调用,分别是 setValue 和 activeStateChanged 的时候。那么我们可以看看这个方法传值是否为空有什么区别。当do-while循环开始执行的时候,会先去判断initiator对象(该对象是观察者)是否为空,然后执行considerNotify方法
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
}
这个方法中有3个if判断
1> !observer.mActiveobserver的全局状态是不是可见状态。
2>!observer.shouldBeActive()判断当前的观察者对象是否是处在可见状态
3>observer.mLastVersion >= mVersion 一个版本控制操作,每次setValue的时候mVersion就会执行++操作
4> observer.mObserver.onChanged((T) mData) 最后就会执行到观察者的 onChanged方法
3) 在onChanged的时候调用到mData,mData是用volatile 关键词修饰的,那么久有一定可能会有多线程安全问题
private volatile Object mData
4)setValue 和 postValue的区别:
主线程用setValue,而子线程用 postValue。但是其实最后postValue也是通过线程切换之后调用setValue。
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
5)observeForever 跟上述的流程相比会更加简单,
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
assertMainThread("observeForever");
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing instanceof LiveData.LifecycleBoundObserver) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
wrapper.activeStateChanged(true);
}
它在绑定观察者使用的时候直接调用activeStateChanged方法,省去了UI状态的判断。
6)多线程访问、递归调用的时候会根据下面两个变量进行判断
private boolean mDispatchingValue;//默认值false
private boolean mDispatchInvalidated;//默认值false
这两个变量默认值都是false,同时使用的地方只有这个方法一个位置。当前observe观察者还未调用 onChanged方法时,新的一次setValue/ postValue 发送消息时,走if判断,跳出do-while循环直接发下一个被观察者的状态,这个就是连续发送消息时,LiveData为何会在被观察者处收到最后一条消息。