Android 面试总结 - LiveData (二)| 8月更文挑战

1,351 阅读6分钟

本文是 Android 面试总结 - LiveData 的续集。

上一集中剩下下方两个问题尚未解决:

  1. 粘性事件原理,怎么防止数据倒灌
  2. 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 会分发值。

  1. 调用 setValue 和 postValue 并且 LifecycleOwner 处于活跃状态时
  2. LiveData 有值,并且处于活跃状态时,调用 LiveData#observe 订阅观察者
  3. 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怎么用 已经解答完啦。