本文是 Android 面试总结 - LiveData 的续集。
上一集中剩下下方两个问题尚未解决:
- 粘性事件原理,怎么防止数据倒灌
- observeForever怎么用
粘性事件,说白了是被观察者原本有值,当新注册观察者时,被观察者会将旧值发送给观察者。
来看看 LiveData 粘性事件的原理:
我们知道在 LiveData#observe 订阅观察者时,最终依靠 LifecycOwner 来实现对生命周期的感知
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);
}
我们在上一篇文章中使用的 LifecycleOwner 是 Activity,生命周期相关实现最终是在 ComponentActivity 中。ComponentActivity 实现了 LifecycleOwner 接口
public interface LifecycleOwner {
/**
* Returns the Lifecycle of the provider.
*
* @return The lifecycle of the provider.
*/
@NonNull
Lifecycle getLifecycle();
}
LifecycleOwner 接口只有一个方法,只能去看 ComponentActivity 对 LifecycleOwner#getLifecycle 的具体实现
private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
// ComponentActivity#getLifecycle
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
在 LiveData#observe 方法中调用 owner.getLifecycle().addObserver(wrapper);
接下来再看 ComponentActivity#mLifecycleRegistry 对象的 addObserver 方法
// LifecycleRegistry#addObserver
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
// 初始 State
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
// 对 observer 做一次包装
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
...
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
...
// 这里会把初始的 initialState 转为 Lifecycle.Event.ON_CREATE
final Event event = Event.upFrom(statefulObserver.mState);
// 只关注关键代码
statefulObserver.dispatchEvent(lifecycleOwner, event);
...
}
...
}
ObserverWithState 是 LifecycleRegistry 的静态内部类
static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
// 将 observer 赋值给 mLifecycleObserver
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = event.getTargetState();
mState = min(mState, newState);
// 关键关键
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
在上面 LifecycleRegistry#addObserver 方法中 会调用 ObserverWithState 对象statefulObserver.dispatchEvent(lifecycleOwner, event);
最终是调用了我们在 LiveData#observe 方法中创建的 LifecycleBoundObserver 对象 wrapper 的 onStateChanged 方法,再回顾下
@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);
}
这时候我们就很清晰了。接下来可以看 LifecycleBoundObserver 对 dispatchEvent 的具体实现了
LifecycleBoundObserver 源码
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@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(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
// 获取当前 LifecycleOwner 的状态,界面已经显示的情况下为 Lifecycle.State.ON_RESUME
Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
// 当状态为 DESTROYED 时自动取消注册。
if (currentState == DESTROYED) {
removeObserver(mObserver);
return;
}
Lifecycle.State prevState = null;
// 判断状态有没有改变,这时 currentState 的值是 Lifecycle.State.ON_RESUME 不为 null
// 所以这里会进入 while 循环
while (prevState != currentState) {
// 赋值 prevState
prevState = currentState;
// 关键代码哟 shouldBeActive() 这时是返回的 true 属于活跃状态
activeStateChanged(shouldBeActive());
// 获取当前最新状态
currentState = mOwner.getLifecycle().getCurrentState();
}
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
activeStateChanged 是 LifecycleBoundObserver 父类 ObserverWrapper 中的方法
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) {
// 第一次创建对象 mActive 没有赋值,则为默认值 false
// 刚刚调用 activeStateChanged 方法时,传入的值是 shouldBeActive() 返回的 true
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
changeActiveCounter(mActive ? 1 : -1);
if (mActive) {
// 关键代码
dispatchingValue(this);
}
}
}
activeStateChanged 中调用了 dispatchingValue 并且传入了 this#ObserverWrapper 对象。我们在上一集中知道,在 setValue 和 postValue 方法,最终都会调用 dispatchingValue(null) 来分发数据给观察者们。再回顾下 LiveData#dispatchingValue
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;
}
LiveData#considerNotify
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;
}
// 因为 observer 是新创建的 所以这里的 observer.mLastVersion 应为初始值 LiveData#START_VERSION 为 -1
// 而 mVersion 因为 LiveData 不是第一次分发值,所以 mVersion 肯定是大于初始值 START_VERSION -1 的
// 故此条件不成立
if (observer.mLastVersion >= mVersion) {
return;
}
// 将 LiveData 的 mVersion 赋值给 observer.mLastVersion
observer.mLastVersion = mVersion;
// 调用了 onChanged 也就是我们在 LiveData.observe 传入的 Observer 的 Observer 对象的 onChanged
observer.mObserver.onChanged((T) mData);
}
这时候我们可以总结一下有几种情况 LiveData 会分发值。
- 调用 setValue 和 postValue 并且 LifecycleOwner 处于活跃状态时
- LiveData 有值,并且处于活跃状态时,调用 LiveData#observe 订阅观察者
- LiveData 有新值,也就是 ObserverWrapper 的 mLastVersion 小于 LiveData 的 mVersion,LifecycleOwner 从不活跃状态转为活跃状态时
根据第三种情况:我们是不是可以回答一个面试问题了呢:
在 ActivityA 注册了 LiveData 的观察者 ObserverA,此时我们跳转到了 ActivityB, 业务上多次调用了 LiveData 的 setValue 或 postValue,问 这是 LiveData 的观察者 ObserverA 会收到几次值,为什么?再返回到 ActivityA 时,会发生什么?
LiveData 的粘性事件原理,可以回答了,在 LiveData 有值时,调用 LiveData#observe 订阅观察者,会收到旧值。结合上面源码过程,相信你可以征服面试官。
数据倒灌,其实就是 LiveData 粘性事件的最终结果。怎么防止呢?看大神的文吧,小弟不在这儿班门弄斧了:LiveData 数据倒灌 背景缘由全貌 独家解析
下面我在看下第5个问题 5. observeForever怎么用
LiveData#observeForever 方法其实用的比较少,但是如果将 LiveData 作为事件总线机制或者配置之类的东东时,它就会派上用场。
/**
* Adds the given observer to the observers list. This call is similar to
* {@link LiveData#observe(LifecycleOwner, Observer)} with a LifecycleOwner, which
* is always active. This means that the given observer will receive all events and will never
* be automatically removed. You should manually call {@link #removeObserver(Observer)} to stop
* observing this LiveData.
* While LiveData has one of such observers, it will be considered
* as active.
* 将给定的观察者添加到观察者列表中。此调用类似于{@link LiveData#observe(LifecycleOwner,observator)},其LifecycleOwner始终处于活动状态。这意味着给定的观察者将接收所有事件,并且永远不会被自动删除。您应该手动调用{@link#removeObserver(Observer)}以停止观察此LiveData。
* 虽然LiveData有一个这样的观察者,但它将被视为活动的。
* <p>
* If the observer was already added with an owner to this LiveData, LiveData throws an
* {@link IllegalArgumentException}.
* 如果观察者已经添加了此LiveData的所有者,LiveData将抛出一个{@link IllegalArgumentException}。
*
* @param observer The observer that will receive the events
*/
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
assertMainThread("observeForever");
// 包装类 AlwaysActiveObserver
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing instanceof LiveData.LifecycleBoundObserver) {
// 如果已经添加过了此观察者 则 抛异常
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
// 这里这里是一个关键
wrapper.activeStateChanged(true);
}
AlwaysActiveObserver 是 LiveData 的内部类
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer<? super T> observer) {
super(observer);
}
@Override
boolean shouldBeActive() {
// 这就是 AlwaysActiveObserver 的关键,他不依赖生命周判断是否活跃,而固定返回 true 表示一直活跃~~!
return true;
}
}
LiveData#observeForever 最后调用了 AlwaysActiveObserver#activeStateChanged 方法 activeStateChanged 是父类 ObserverWrapper 中的方法
// ObserverWrapper#activeStateChanged
void activeStateChanged(boolean newActive) {
// newActive = true
// 这时候 ObserverWrapper 第一次创建 mActive 的值是 boolean 的默认值 false
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
changeActiveCounter(mActive ? 1 : -1);
if (mActive) {
// 又到了分发值的时候啦
dispatchingValue(this);
}
}
因为 LiveData#observeForever 中调用 wrapper.activeStateChanged(true) 传入的是 true 所以最后会走 dispatchingValue(this);接下来就于上面分析粘性事件时 dispatchingValue(this) 后续逻辑一样咯,不在分析了。
AlwaysActiveObserver 不依赖生命周期了,所以不会像 LifecycleBoundObserver 在生命周期变为 DESTROYED 时调用 LiveData#removeObserver 从 LiveData#mObservers Map 中移除自身,所以我们在使用 LiveData#observeForever 时应在不需要的时候调用 LiveData#removeObserver ,否则可能会发生内存泄露呢。
到这儿第5个问题 5. observeForever怎么用 已经解答完啦。