Android Jetpack LiveData 源码详解
LiveData 是 Android Jetpack 架构组件中用于实现观察者模式的数据持有类,它具有生命周期感知能力。下面我将从核心设计、关键实现和源码分析三个方面深入解析 LiveData。
一、核心设计思想
- 观察者模式:LiveData 采用观察者模式,允许 UI 组件观察数据变化
- 生命周期感知:自动管理订阅者的生命周期,避免内存泄漏
- 数据一致性:确保 UI 始终显示最新的数据状态
- 共享资源:多个观察者可以安全地观察同一个 LiveData 实例
二、核心类结构
LiveData
├── MutableLiveData
├── MediatorLiveData
└── ComputationsLiveData (internal)
三、源码深度解析
1. 核心方法:observe()
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
// 检查是否在主线程
assertMainThread("observe");
// 如果生命周期已经是DESTROYED状态,直接忽略
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
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);
}
2. 生命周期感知实现:LifecycleBoundObserver
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@NonNull final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
this.mOwner = owner;
}
@Override
boolean shouldBeActive() {
// 只有当生命周期至少是STARTED状态时才认为是活跃的
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
// 如果生命周期变为DESTROYED状态,自动移除观察者
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);
}
}
3. 数据分发机制:setValue()
@MainThread
protected void setValue(T value) {
// 必须在主线程调用
assertMainThread("setValue");
// 版本号递增
mVersion++;
// 保存数据
mData = value;
// 分发数据
dispatchingValue(null);
}
private 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;
}
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);
}
4. 数据转换:Transformations
public static <X, Y> LiveData<Y> map(
@NonNull LiveData<X> source,
@NonNull final Function<X, Y> mapFunction) {
final MediatorLiveData<Y> result = new MediatorLiveData<>();
result.addSource(source, new Observer<X>() {
@Override
public void onChanged(@Nullable X x) {
result.setValue(mapFunction.apply(x));
}
});
return result;
}
public static <X, Y> LiveData<Y> switchMap(
@NonNull LiveData<X> source,
@NonNull final Function<X, LiveData<Y>> switchMapFunction) {
final MediatorLiveData<Y> result = new MediatorLiveData<>();
result.addSource(source, new Observer<X>() {
LiveData<Y> mSource;
@Override
public void onChanged(@Nullable X x) {
LiveData<Y> newLiveData = switchMapFunction.apply(x);
if (mSource == newLiveData) {
return;
}
if (mSource != null) {
result.removeSource(mSource);
}
mSource = newLiveData;
if (mSource != null) {
result.addSource(mSource, new Observer<Y>() {
@Override
public void onChanged(@Nullable Y y) {
result.setValue(y);
}
});
}
}
});
return result;
}
四、关键设计亮点
-
版本控制机制:
- 每个数据更新都会增加
mVersion - 观察者记录最后接收的版本号
mLastVersion - 避免重复通知和数据倒流
- 每个数据更新都会增加
-
线程安全设计:
setValue()必须主线程调用postValue()内部使用ArchTaskExecutor切换到主线程- 观察者回调保证在主线程执行
-
高效更新策略:
- 使用
mDispatchingValue和mDispatchInvalidated标志处理并发修改 - 活跃状态变化时只通知状态变化的观察者
- 使用
-
资源清理:
- 自动移除 DESTROYED 状态的观察者
- 使用
WeakReference避免内存泄漏
五、使用场景分析
- 普通数据观察:
liveData.observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
// 更新UI
}
});
- 数据转换:
LiveData<String> userName = Transformations.map(userLiveData, user -> {
return user.firstName + " " + user.lastName;
});
- 多源数据合并:
MediatorLiveData<Boolean> isEnabled = new MediatorLiveData<>();
isEnabled.addSource(loginLiveData, x -> isEnabled.setValue(x != null));
isEnabled.addSource(permissionLiveData, x -> isEnabled.setValue(Boolean.TRUE.equals(x)));
LiveData 通过这种设计实现了安全、高效的生命周期感知型数据观察,成为 Android 现代架构的核心组件之一。