LiveData原理解析
LiveData是一个数据持有者类,可以在给定的生命周期中观察到。
observe观察数据变化
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
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);
}
observe被要求在主线程调用,并且传递生命周期相关的LifecycleOwner,
- 检查观察者生命周期状态
- 组合LifecycleOwner与observer生成LifecycleBoundObserver并以observer为key存起来
- 限制观察者只能与一个生命周期绑定并且控制不要重复观察
- 由于Lifecycle.addObserver会回调当前生命周期,所以observe时会收到一次数据变化
- LifecycleBoundObserver在生命周期销毁时会移除对LiveData的观察,不需要调用者关心解绑时机
- 数据变化时通过判断Observer的生命周期状态+当前数据版本号判断是否回调数据变化
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
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);
}
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 != null && existing instanceof LiveData.LifecycleBoundObserver) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
wrapper.activeStateChanged(true);
}
与observe相似,区别在于
observeForever不与生命周期绑定。
记录的观察者为AlwaysActiveObserver
-
数据变化时判断的Observer的生命周期方法变为不关心生命周期,变化了就回调
boolean shouldBeActive() { return true; }
不会自动解除绑定,需要主动解除绑定
ObserverWrapper观察者对象
ObserverWrapper是LiveData缓存的观察者对象,它是LifecycleBoundObserver与AlwaysActiveObserver的父类
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();
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);
}
}
}
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@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(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer super T> observer) {
super(observer);
}
@Override
boolean shouldBeActive() {
return true;
}
}
private static void assertMainThread(String methodName) {
if (!ArchTaskExecutor.getInstance().isMainThread()) {
throw new IllegalStateException("Cannot invoke " + methodName + " on a background"
+ " thread");
}
}
- Lifecycle转化到观察者对象里来讲就是一个mActive(是否活跃)状态,如果活跃,则数据变化我就回调mObserver的onChanged方法,如果不活跃则等你重新活跃了再回调给你数据变更。
- shouldBeActive() 观察者是否活跃
- isAttachedTo(LifecycleOwner owner) 判断是否已经设置过监听
- detachObserver() 观察者被移除时回调 LifecycleBoundObserver在detachObserver时会移除对lifecycle的监听
- activeStateChanged(boolean newActive) 活跃状态变更时回调
setValue
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
更新LiveData数据,被要求在主线程调用,调用后数据及数据版本会变化,随后通知观察者
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, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
该方法也做了并发兼容,并支持回调指定的ObserverWrapper,用于在ObserverWrapper从非活跃变成活跃状态并且数据版本发生变化时回调自身。
postValue
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
postValue也是更新LiveData数据,只是该方法支持在子线程调用,调用后通过往主线程Handle抛mPostValueRunnable调用setValue实现数据更新
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue);
}
};
若产生并发则通过替换mPendingData的值来更新数据,而不会重复往主线程抛setValue方法。
LiveData的缺点
LiveData的特性是观察者只关心数据变化的最终值,如果你不太关心数据变化的中间值,只要数据变化了能通知到你最新的值的话LiveData已经够用了,甚至项目中它已经可以取代事件总线的地位。
但如果你需要数据的每一次变化都通知到你的话,就不要用LiveData了。以下场景存在数据丢失的问题
- postValue高并发情况下只会修改mPendingData值,而不会每次都调用setValue
- observe更是存在该问题,非活跃状态变成活跃状态时只会收到当前最新值的一次变更通知
只有observeForever+setValue没有这种问题,条件有些苛刻,不了解原理的话容易踩坑。