LiveData简介
它是一个绑定了给定的生命周期的数据持有类,每一个注册的observer
都和一个生命周期LifecycleOwner
串联在一起,只有在LifecycleOwner在活跃状态时才会通知修改数据。
1. 使用分析
- 可以使用
observeForever
,这样代表任何时候都是活跃状态,所以需要手动的removeObserver
才可以; - 另一种可以使用
observe
,它可以和当前的生命周期绑定,例如activities
,fragments
中,这样会在onDestory
的时候自定的解绑定; LiveData
本身有两个方法onActive
和onInactive
,可以用来释放不需要的资源- 它是用来设计的在
viewmodel
独立持有数据,也可以解耦的方式来分享数据。
还需要看一下生命周期的状态:
状态(枚举)值从低到高 | 介绍 |
---|---|
DESTROYED | 执行ON_DESTORY 之后 |
INITIALIZED | 默认初始状态 |
CREATED | 执行ON_CREATE 之后,或者在ON_STOP 之后 |
STARTED | 执行ON_START 之后,或者在ON_PAUSE 之后 |
RESUMED | 执行ON_RESUME 之后 |
可以查看官方文档,加深对于生命周期状态的理解:
2. 源码分析
来看一下observer
这个方法的功能:
- 只有在
active
时才会接收到数据 - 会自动的解绑定,在
DESTROYED
状态的时候 - 如果在
inactive
过程中改变了数据,从inactive
到activive
会接收到最新一次的可用数据 - 如果在
DESTROYED
时observer
会自动忽略此次调用 - 如果给定的所有者、观察者已经在列表中,则忽略调用。
- 如果观察者已经在另一个所有者的列表中,
LiveData
会抛出一个异常
分析一下源码:
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
//--4.如果在`DESTROYED`时`observer`会自动忽略此次调用
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//--1.进行和声明周期的绑定
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
//--6. 如果观察者已经在另一个所有者的列表中,LiveData会抛出一个异常
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
//--5. 如果给定的所有者、观察者已经在列表中,则忽略调用。
if (existing != null) {
return;
}
owner.getLifecycle().addObserver(wrapper);
}
LifecycleBoundObserver
是一个继承了ObserverWrapper
和实现了GenericLifecycleObserver
接口的类
ObserverWrapper
:持有当前的observer
,提供数据更新方法GenericLifecycleObserver
:代表的是生命周期变化,会有回调,生命周期状态改变,再调用ObserverWrapper
提供的activeStateChanged
方法进行对应的数据变化
我们来看一下LifecycleBoundObserver
中具体的方法:
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
//--2.会自动的解绑定,在DESTROYED状态的时候
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
从上述的源码分析可以看到,我们常用的方法observer
对于传递进来的参数,使用LifecycleBoundObserver
进行了绑定,然后存储在mObservers
,进行了一些合法性的校验
private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers = new SafeIterableMap<>();
最终还是会到
owner.getLifecycle().addObserver(wrapper);
那么我们就有必要看看这行代码到底干了什么了。
LiveData
的分析离不开使用Lifecycle
,所以先看一下Lifecycle
吧,Lifecycle
和Observer
是一个一对多的关系,我们可以有很多的Observer
来监听当前的Lifecycle
的状态变化
- 在
fragment
和FragmentActivity
中有相应的实现,直接使用getLifecycle
即可 - 在
LifecycleOwner
相关的生命周期方法之后,才会执行ON_CREATE
,ON_START
,ON_RESUME
事件 - 在
LifecycleOwner
相关的生命周期方法之前,才会执行ON_PAUSE
,ON_STOP
,ON_DESTROY
,例如在onStart
之后执行,在onStop
之前执行,这样会保证状态的正确性 - 在
java7
使用注解方式,可以接受参数,第一个必须是LifecycleOwner
,在java8
通过实现DefaultLifecycleObserver
这个来做
具体的实现类是LifecycleRegistry
,我们来看一下关键的方法
addObserver
,将当前的observer
和生命周期状态绑定起来,具体的实现类是ObserverWithState
,持有LifecycleBoundObserver
和当前的生命周期状态;
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
//--1.将当前的observer和生命周期状态绑定
//非DESTROYED时,都为INITIALIZED状态
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
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;
// 计算当前的状态,取mObserverMap的observer前一个状态和INITIALIZED进行比较选最小的状态
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
//如果是在onCreate中注册的话,那么mState是INITIALIZED,不会进入这一循环当中;
//但是如果我们是在onStart中调用的addObserver的话,那么tartgetState会大于INITIALIZED,就会进入次循环来更新当前的observer的值;
//也就是说我们无论在哪里调用的addObserver,只要在生命周期回调的时候就会有对应的方法被触发看是否需要更新成最近一次的值
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--;
}
具体看一下ObserverWithState
这个类,持有Observer
和调用addObserver
时的状态
static class ObserverWithState {
State mState;
GenericLifecycleObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.getCallback(observer);
mState = initialState;
}
//当event进行改变时会调用此方法
void dispatchEvent(LifecycleOwner owner, Event event) {
//生命周期改变时会调用此方法,最终到LiveData的activeStateChanged方法中,用来更新数据的
State newState = getStateAfter(event);
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);
//重新设置当前的状态
mState = newState;
}
}
在LifecycleRegistry
中有一个handleLifecycleEvent
方法,当绑定了生命周期的事件后,只要有生命周期的事件改变了,就会调用此方法修改当前的mState
,这样结合addObserver
中的方法,如果注册的状态小于当前的状态,那么就会更新数据了,这样的话看着更清楚。我们重点看一下生命周期改变的sync
方法
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
Log.w(LOG_TAG, "LifecycleOwner is garbage collected, you shouldn't try dispatch "
+ "new events from it.");
return;
}
while (!isSynced()) {
mNewEventOccurred = false;
// no need to check eldest for nullability, because isSynced does it for us.
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
//后退策略,生命周期从onPause->onStop->onDestory时会走这个
backwardPass(lifecycleOwner);
}
Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
//前进策略,生命周期从onCreate->onStart->onResume时会走这个
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
只看一个就好了,我们看一下forwardPass
方法:
private void forwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
mObserverMap.iteratorWithAdditions();
while (ascendingIterator.hasNext() && !mNewEventOccurred) {
Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
ObserverWithState observer = entry.getValue();
while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
pushParentState(observer.mState);
//看着和addObserver的方法一样的,就是现在的生命周期状态变化了,所以要通过LifecycleObserver更新了
observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
popParentState();
}
}
}
好了,注册一个observer
的过程我们清楚了,我们画一下对应的函数调用图
在INITIALIZED
状态时进行注册的,也就是在onCreate
中进行的observer
,函数调用图:
在INITIALIZED
状态之后再进行注册的,也就是不在onCreate
中进行observer
,而是在onStart
等之后的函数调用图:
当Lifecycle
生命周期进行变换时的函数调用:(以生命周期向前为例,例如onCreate->onStart,onStart->onResume)
我们再看一下更新数据的逻辑,直接看setValue
方法,
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
//更新版本
mVersion++;
//当前最新的值
mData = value;
dispatchingValue(null);
}
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
//initiator为null,所以会走到else中
if (initiator != null) {
//当生命周期有变化时会走到这里更新数据
considerNotify(initiator);
initiator = null;
} else {
//会将注册的所有observer进行遍历,然后通知当前修改
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
最后我们看到,在considerNorify
用来更新observer
的数据
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
// Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
//
// we still first check observer.active to keep it as the entrance for events. So even if
// the observer moved to an active state, if we've not received that event, we better not
// notify for a more predictable notification order.
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//noinspection unchecked
// 实际更新数据的地方
observer.mObserver.onChanged((T) mData);
}
我们使用setValue
更新数据时的函数调用:
以上就是对于LiveData
的源码分析。