- LiveData is a data holder class that can be observed within a given lifecycle.
正如注释所说,LiveData是一个数据持有容器,并且该容器可以感知生命周期的变化,在合适的时机通知观察者数据的变更。
- 首先定义几个名词,
LifecycleOwner owner
这里暂且称之为生命周期感知者
,简称感知者
吧,Observer<? super T> observer
是外部传入的回调接口,内部会被包装成ObserverWrapper
,在此称之为观察者
。
-
LiveData
是一个抽象类,其子类常用的有MutableLiveData
,MediatorLiveData
和RoomTrackingLiveData
。继承关系如下:
public abstract class LiveData<T> {}
// 只是开放了postValue(T value)和setValue(T value)数据操作方法
public class MutableLiveData<T> extends LiveData<T> {}
// 依赖监听其他或多个LiveData的变化
public class MediatorLiveData<T> extends MutableLiveData<T> {}
// Room Database框架,暂不分析
class RoomTrackingLiveData<T> extends LiveData<T> {}
- 一般情况下,首先会构造一个
LiveData
对象,然后注册一个LifecycleOwner
生命周期感知者(一般是Fragment
或者Activity
)和数据变化通知的回调接口,内部把回调接口包装成观察者ObserverWrapper
:
一般请用步骤:
LiveData<User> liveData = new MutableLiveData();
liveData.observe(this, new Observer<User>() {
@Override
public void onChanged(User user) {
// do something with the newest data
}
});
<LiveData.java>
static final int START_VERSION = -1;
private int mVersion;// 这个值是用于判断是否已经通知过,保证每次通知都是最新的数据值
public LiveData(T value) {
mData = value;
mVersion = START_VERSION + 1;// 默认0开始,因为该构造默认已经将数据赋值
}
public LiveData() {
mData = NOT_SET;
mVersion = START_VERSION;// 默认-1开始
}
- 注意
observe
必须在主线程调用,接着看下observe
方法中的实现:
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
// 检查是否在主线程
assertMainThread("observe");
// 如果当前感知者的生命周期处于Destroy状态,直接忽略
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
// 将感知者和回调接口包装成观察者对象,具备感知生命周期和触发外部回调的功能
// 生命周期感知也是一种观察者模型
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
// 一种类似Map的数据结构,缓存当前观察者
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
// 一个回调接口只能绑定一个观察者
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
// 同一个观察者只能添加一次
if (existing != null) {
return;
}
// 添加生命周期监听
owner.getLifecycle().addObserver(wrapper);
}
- 这个
LifecycleBoundObserver
观察者中实现了LifecycleObserver
,具备生命周期的感知能力:
// 对生命周期变化观察者的封装
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
// 感知者
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
// 生命周期在onStart之后才会被标记为激活状态
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
// 生命周期状态变更回调
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
// 如果感知者的生命周期进入destroy,则移除该观察者(同时释放了该感知者),避免内存泄漏
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
// 通知状态变更(改变父类的mActive变量值),在分发通知时会用于判断
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
// 移除生命周期监听
mOwner.getLifecycle().removeObserver(this);
}
}
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;// 是否可见激活状态
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<? super T> observer) {
mObserver = observer;
}
abstract boolean shouldBeActive();// 是否被激活,LifecycleBoundObserver中onStart之后为true
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
void detachObserver() {
}
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
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();
}
if (mActive) {
dispatchingValue(this);
}
}
}
- 接着,如果我们需要改变LiveData中的数据时,只需调用其setValue或者postValue方法:
// 缓存数据对象
private volatile Object mData;
// setValue只能在主线程调用
@MainThread
protected void setValue(T value) {
// 判断线程
assertMainThread("setValue");
// 标记操作数
mVersion++;
// 赋值数据
mData = value;
// 分发通知各个观察者
dispatchingValue(null);
}
// 只是切换线程的作用,可以在子线程调用
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
// 缓存当前改变的数据
// 在runnable中会重新标记为NOT_SET,避免并发问题
mPendingData = value;
}
if (!postTask) {
return;
}
// 该runnable最终还是会调用setValue
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue);
}
};
- 典型的观察者模式,接下去就是通知各个观察者数据的变化了:
@SuppressWarnings("WeakerAccess") /* synthetic access */
void dispatchingValue(@Nullable ObserverWrapper initiator) {
// mDispatchingValue第一次默认false
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
// mDispatchingValue赋值true
// 此时如果下一次setValue触发,上面的mDispatchInvalidated变为true,下面for循环打断退出,并且重新执行do-while循环,这样就能保证再次分发通知是最新的数据值(这几个标记的boolean变量主要也是处理并发问题)
mDispatchingValue = true;
do {
mDispatchInvalidated = false;// 默认只会执行一次do-while循环
if (initiator != null) {
// 当一个observer从非激活到激活状态时会进入该分支
// 该分支只会通知该observer
considerNotify(initiator);
initiator = null;
} else {
// 一般进入该分支
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
// 遍历取出集合中的ObserverWrapper进行通知
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {// 如果数据在遍历期间有新的变更,则后面未通知到观察者不再通知
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
// 通知观察者数据变化
private void considerNotify(ObserverWrapper observer) {
// 观察者是否处于生命周期可见状态,mActive默认为false不进行通知,但是在LifecycleObserver生命周期onStart之后会赋值true
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.
// 再次检查observer的生命周期是否onStart之后
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
// mLastVersion默认为-1,一般mVersion在LiveData的构造方法中赋值-1
// 另外一个构造中赋值0,在setValue中会++变为0或者1
// 保证同一个observer对象对该次数据变化只能接收一次通知
if (observer.mLastVersion >= mVersion) {
// 如果version相等,表示该数据已经通知过了
return;
}
// 标识该次数据变化已经通知过了
observer.mLastVersion = mVersion;
//noinspection unchecked
// 回调通知
observer.mObserver.onChanged((T) mData);
}
// 对于从非激活状态到激活状态,会主动请求接收通知
private abstract class ObserverWrapper {
...
void activeStateChanged(boolean newActive) {
// 生命周期状态没变,忽略
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
// 是否不存在激活状态的observer
boolean wasInactive = LiveData.this.mActiveCount == 0;
// 如果observer生命周期激活状态,激活的observer数量+1,否则-1
LiveData.this.mActiveCount += mActive ? 1 : -1;
// 一般情况可以忽略该判断
if (wasInactive && mActive) {
onActive();// 回调通知,MediatorLiveData中有实现
}
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive();// 回调通知,MediatorLiveData中有实现
}
// 如果从未激活到激活,会重新分发一次
if (mActive) {
dispatchingValue(this);
}
}
}
- 代码不多,内部就是一个典型的观察者模型,主要核心是在通知观察者的过程中引入了生命周期的感知,对于处于激活状态的observer才进行通知更新,当observer从非激活到激活状态也会收到通知。重点是在observer生命周期结束(Destroy)时,会自动释放observer的引用,从而避免了内存泄漏。
网友评论