这是我参与更文挑战的第22天,活动详情查看: 更文挑战
源码分析
LiveData#observe
private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
new SafeIterableMap<>();
@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);
}
复制代码
我们调用observer()
时,传递了两个参数,第一个是LifecycleOwner
接口实例,而我们继承的AppCompatActivity
的父类就已经实现了这个接口,所以我们传this
即可;第二个参数Observer
就是我们观察的回调。
先判断是不是主线程,不是就抛异常,然后通过 owner.getLifecycle().getCurrentState()
获取状态,判断是否已经被销毁,如果已经被销毁,直接返回(因为已经说过只对处于活跃状态的组件做更新);
接着将owner和observer构造成LifecycleBoundObserver
实例,这是一个内部类,里面有关于状态变换的一系列操作,待会详细分析;
然后将observer和wrapper存入map缓存中,如果observer缓存已存在并且已经和另一个LifecycleOwner
绑定,则抛出异常;如果缓存已经存在则直接忽略;
即一个 Observer 实例,只能绑定一个 LifecycleOwner,而一个 owner 可以绑定多个 Observer 实例;
最后调用addObserver方法将LifecycleBoundObserver
实例和LifecycleOwner
绑定。而addObserver是调用了LifecycleRegistry
类的实现。
当 owner (Activity 或者 fragment) 生命周期变化的时候,会回调 LifecycleBoundObserver 的 onStateChanged 方法,onStateChanged 方法又会回调 observer 的 onChange 方法。
LifecycleBoundObserver
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 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;
// 激活状态的 observer 个数从 0 到 1
if (wasInactive && mActive) {
onActive();// 空实现,一般让子类去重写
}
// 激活状态的 observer 个数从 1 到 0
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive();// 空实现,一般让子类去重写
}
// 激活状态,向观察者发送 LiveData 的值
if (mActive) {
dispatchingValue(this);
}
}
}
复制代码
我们来看一下 LifecycleBoundObserver
,继承 ObserverWrapper
,实现了 GenericLifecycleObserver
接口。而 GenericLifecycleObserver
接口又实现了 LifecycleObserver
接口。它包装了我们外部的 observer,有点类似于代理模式。我们可以回顾下Lifecycle
组件相关的内容。当组件(Fragment、Activity)生命周期变化时会通过onStateChanged()方法回调过来。
GenericLifecycleObserver#onStateChanged
Activity 回调周期变化的时候,会回调 onStateChanged ,会先判断 mOwner.getLifecycle().getCurrentState() 是否已经 destroy 了,如果。已经 destroy,直接移除观察者。这也就是为什么我们不需要手动 remove observer 的原因。
如果不是销毁状态,会调用 activeStateChanged 方法 ,携带的参数为 shouldBeActive() 返回的值。
而当 lifecycle 的 state 为 STARTED 或者 RESUMED 的时候,shouldBeActive 方法的返回值为 true,即表示激活。
activeStateChanged 方法中,,当 newActive 为 true,并且不等于上一次的值,会增加 LiveData 的 mActiveCount 计数。接着可以看到,onActive 会在 mActiveCount 为 1 时触发,onInactive 方法则只会在 mActiveCount 为 0 时触发。即回调 onActive 方法的时候活跃的 observer 恰好为 1,回调 onInactive 方法的时候,没有一个 Observer 处于激活状态。
当 mActive 为 true 时,会促发 dispatchingValue 方法。
@SuppressWarnings("WeakerAccess") /* synthetic access */
void dispatchingValue(@Nullable ObserverWrapper initiator) {
// 如果正在处理,直接返回
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
// initiator 不为 null,调用 considerNotify 方法
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else { // 为 null 的时候,遍历所有的 obsever,进行分发
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
// 分发完成,设置为 false
mDispatchingValue = false;
}
复制代码
其中 mDispatchingValue, mDispatchInvalidated 只在 dispatchingValue 方法中使用,显然这两个变量是为了防止重复分发相同的内容。当 initiator 不为 null,只处理当前 observer,为 null 的时候,遍历所有的 obsever,进行分发
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);
}
复制代码
- 如果状态不是在活跃中,直接返回,这也就是为什么当我们的 Activity 处于 onPause, onStop, onDestroy 的时候,不会回调 observer 的 onChange 方法的原因。
- 判断数据是否是最新,如果是最新,返回,不处理
- 数据不是最新,回调 mObserver.onChanged 方法。并将 mData 传递过去
LiveData#setValue
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
复制代码
setValue 方法中,首先,断言是主线程,接着 mVersion + 1; 并将 value 赋值给 mData,接着调用 dispatchingValue 方法。dispatchingValue 传递 null,代表处理所有 的 observer。
这个时候如果我们依附的 activity 处于 onPause 或者 onStop 的时候,虽然在 dispatchingValue 方法中直接返回,不会调用 observer 的 onChange 方法。但是当所依附的 activity 重新回到前台的时候,会促发 LifecycleBoundObserver onStateChange 方法,onStateChange 又会调用 dispatchingValue 方法,在该方法中,因为 mLastVersion < mVersion。所以会回调 obsever 的 onChange 方法,这也就是 LiveData 设计得比较巧妙的一个地方
同理,当 activity 处于后台的时候,您多次调用 livedata 的 setValue 方法,最终只会回调 livedata observer 的 onChange 方法一次。
LiveData#postValue
protected void postValue(T value) {
boolean postTask;
// 锁住
synchronized (mDataLock) {
// 当前没有人在处理 post 任务
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
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue);
}
};
复制代码
- 首先,采用同步机制,通过 postTask = mPendingData == NOT_SET 有没有人在处理任务。 true,没人在处理任务, false ,有人在处理任务,有人在处理任务的话,直接返回
- 调用 AppToolkitTaskExecutor.getInstance().postToMainThread 到主线程执行 mPostValueRunnable 任务。
LiveData#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);
}
复制代码
因为 AlwaysActiveObserver 没有实现 GenericLifecycleObserver 方法接口,所以在 Activity o生命周期变化的时候,不会回调 onStateChange 方法。从而也不会主动 remove 掉 observer。因为我们的 obsever 被 remove 掉是依赖于 Activity 生命周期变化的时候,回调 GenericLifecycleObserver 的 onStateChange 方法。
时序图
借用网上的一张图
LiveData主要涉及到的时序有三个:
- 在Fragment/Activity中通过LiveData.observer()添加观察者(observer()方法中的第二个参数)。
- 根据Fragment/Activity生命周期发生变化时,移除观察者或者通知观察者更新数据。
- 当调用LiveData的setValue()、postValue()方法后,通知观察者更新数据。
todo
NetworkBoundResource
权限
总结
LiveData优点
1. 确保UI符合数据状态 LiveData遵循观察者模式。 当生命周期状态改变时,LiveData会向Observer发出通知。 您可以把更新UI的代码合并在这些Observer对象中。不必去考虑导致数据变化的各个时机,每次数据有变化,Observer都会去更新UI。
2. 没有内存泄漏 Observer会绑定具有生命周期的对象,并在这个绑定的对象被销毁后自行清理。
3. 不会因停止Activity而发生崩溃 如果Observer的生命周期处于非活跃状态,例如在后退堆栈中的Activity,就不会收到任何LiveData事件的通知。
4.不需要手动处理生命周期 UI组件只需要去观察相关数据,不需要手动去停止或恢复观察。LiveData会进行自动管理这些事情,因为在观察时,它会感知到相应组件的生命周期变化。
5. 始终保持最新的数据 如果一个对象的生命周期变到非活跃状态,它将在再次变为活跃状态时接收最新的数据。 例如,后台Activity在返回到前台后立即收到最新数据。
6. 正确应对配置更改 如果一个Activity或Fragment由于配置更改(如设备旋转)而重新创建,它会立即收到最新的可用数据。
7.共享资源 您可以使用单例模式扩展LiveData对象并包装成系统服务,以便在应用程序中进行共享。LiveData对象一旦连接到系统服务,任何需要该资源的Observer都只需观察这个LiveData对象。
使用 LiveData 对象步骤
LiveData
基于观察者模式实现,并且和LifecycleOwner
进行绑定,而LifecycleOwner
又被Fragment
和Activity实现,所以它可以感知生命周期;在当前的LifecycleOwner不处于活动状态(例如onPasue()
、onStop()
)时,LiveData是不会回调observe()
的,因为没有意义.- 同时
LiveData
只会在LifecycleOwner
处于Active
的状态下通知数据改变,果数据改变发生在非 active 状态,数据会变化,但是不发送通知,等owner
回到 active 的状态下,再发送通知; LiveData
在DESTROYED时会移除Observer
,取消订阅,不会出现内存泄漏postValue
在异步线程,setValue
在主线程- 如果
LiveData
没有被observe()
,那么此时你调用这个LiveData的postValue(…)/value=…,是没有任何作用