本文将对Lifecycle-aware Components
三大组件之一的LiveData
进行分析。
首先,分析一下LiveData
类的结构:
可以看出,
LiveData
给出的方法主要分为以下两类:
- 添加删除observer
- 更新本身存储的数据
接下来将对这两个方面入手分析LiveData
工作机制
添加删除observer
添加observer有两个方法
observeForever(@NonNull Observer<T> observer)
-
observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer)
方法一是将一个生命周期不会变化(保持Lifecycle.Event.ON_RESUME
状态)的LifecycleOwner
作为参数调用的方法二:
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// 进入DESTROYED状态无需继续
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
LifecycleBoundObserver existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && existing.owner != wrapper.owner) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
owner.getLifecycle().addObserver(wrapper);
}
class LifecycleBoundObserver implements GenericLifecycleObserver {
public final LifecycleOwner owner;
public final Observer<T> observer;
public boolean active;
public int lastVersion = START_VERSION;
LifecycleBoundObserver(LifecycleOwner owner, Observer<T> observer) {
this.owner = owner;
this.observer = observer;
}
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(observer);
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
activeStateChanged(isActiveState(owner.getLifecycle().getCurrentState()));
}
void activeStateChanged(boolean newActive) {
if (newActive == active) {
return;
}
active = newActive;
boolean wasInactive = LiveData.this.mActiveCount == 0;
LiveData.this.mActiveCount += active ? 1 : -1;
if (wasInactive && active) {
onActive();
}
if (LiveData.this.mActiveCount == 0 && !active) {
onInactive();
}
if (active) {
dispatchingValue(this);
}
}
}
首先将observer封装成一个LifecycleBoundObserver
对象添加到mObservers中去,和前面介绍的LifecycleRegistry
如出一辙,之后将封装后的observer同时注册到对应的LifecycleOwner
中去,此时依据上节内容,LifecycleRegistry
会将LifecycleBoundObserver
进行进一步封装成为ObserverWithState
,在生命周期发生变化时,通过调用dispatchEvent(LifecycleOwner owner, Event event)
方法通知observer生命周期变更,从而让LifecycleBoundObserver
感知生命周期,在DESTROYED
状态下自动移除。
删除observer与添加逻辑相同,只是多了一步将observer激活状态改为false,对LiveData
内部统计数据(mActiveCount)进行更改。
LiveData值的刷新
LiveData
提供了两种方法对其进行赋值:
- setValue(T value)(主线程赋值)
- postValue(T value)(子线程赋值)
setValue(T value)
首先先对主线程赋值进行一个了解:
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
private void dispatchingValue(@Nullable LifecycleBoundObserver initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
for (Iterator<Map.Entry<Observer<T>, LifecycleBoundObserver>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
private void considerNotify(LifecycleBoundObserver observer) {
if (!observer.active) {
return;
}
if (!isActiveState(observer.owner.getLifecycle().getCurrentState())) {
observer.activeStateChanged(false);
return;
}
if (observer.lastVersion >= mVersion) {
return;
}
observer.lastVersion = mVersion;
//noinspection unchecked
observer.observer.onChanged((T) mData);
}
主要方法在dispatchingValue(@Nullable LifecycleBoundObserver initiator)
中:
- mDispatchingValue -> true代表之前有值刷新尚未广播完成,将mDispatchInvalidated改为true,为false则直接向下进行;
- 将mDispatchingValue设为true表示正在广播,随后判断是对单个observer进行通知或者对所有监听此项的observer进行通知。此时若有新值需要广播,则在对所有监听此项observer进行通知时直接退出重新遍历发送最新值。
considerNotify(LifecycleBoundObserver observer)
方法则是根据当前项的激活状态决定是移除observer还是将值变化通知对应observer进行改变。
postValue(T value)
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
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);
}
};
postValue(T value)
则是先暂时将新值保存,随后将具体调用setValue
方法post到一个依附于主线程的Handle
中去,通过Handle
达到线程切换目的从而通知值刷新。
使用
LiveData
使用时主要是使用子类MutableLiveData
,这个子类实现了Livedata
并公开了两个赋值方法。
小结
LiveData
的工作流程在有了之前LifecycleRegistry
的分析之后变得很清晰:主要是将observer封装后存储,并依托LifecycleRegistry
根据生命周期和自身值变化达到刷新通知observer进行刷新目的。