LiveData 源码解析

LiveData 是什么

基于观察者模式

LiveData 是一种数据持有类,并且可以在给定的生命周期中对数据进行观察。意味着观察者可以和生命周期持有者成对添加。

感知生命周期

和其他可被观察的类不同的是,LiveData 是有生命周期感知能力的,这意味着它可以在 activities, fragments, 或者 services 生命周期是活跃状态(STARTED 或 RESUMED)时更新这些组件。

自动解除数据订阅

要想使用 LiveData(或者这种有可被观察数据能力的类)就必须配合实现了 LifecycleOwner 的对象使用。在这种情况下,当对应的生命周期对象 DESTORY 时,才能移除观察者。这对 Activity 或者 Fragment 来说显得尤为重要,因为他们可以在生命周期结束的时候立刻解除对数据的订阅,从而避免内存泄漏等问题。

源码解析

observe 订阅

observe(LifecycleOwner, Observer) 方法

方法的关键逻辑放在了注释中。

/**
 * 在 owner 生命周期内添加 observer。事件在主线程上调度。
 * 如果 LiveData 已经有了数据,将会被发送到 observer 上。
 * 

* observer 只会在 owner 状态为 {@link Lifecycle.State#STARTED} * 或 {@link Lifecycle.State#RESUMED} 的活跃状态时接收事件。 *

* 如果在 owner 到达 {@link Lifecycle.State#DESTROYED} 状态,observer 会自动被移除。 *

* 在 owner 非活跃状态时发生数据变化,它将不会接收任何更新。 * 当它重新回到活跃状态,它将自动获取最后一次有效的数据。 *

* LiveData 在 LifecyclerOwner 未销毁期间会一直强引用着 observer 和 owner。 * 在 LifecyclerOwner 被销毁后会移除对 observer 和 owner 的引用。 *

* 如果 owner 已经处于 {@link Lifecycle.State#DESTROYED} 状态,LiveData 会忽略这次操作。 *

* 如果 wrapper(owner、observer) 在映射已经存在,LiveData 会忽略这次操作。 * 如果 observer 已经绑定了其他的 owner,LiveData 抛出 {@link IllegalArgumentException}。 */ @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

ObserverWrapper 是 LiveData 内部的 Observer 包装类,而 LifecycleBoundObserver 继承了它并且实现了 LifecycleEventObserver 接口,使其能监听到生命周期的变化。

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) {
        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();
    
    /**
     * 是否已经依附了 LifecycleOwner
     */
    boolean isAttachedTo(LifecycleOwner owner) {
        return false;
    }
    
    /**
     * 解绑 observer
     */
    void detachObserver() {
    }
    
    void activeStateChanged(boolean newActive) {
        if (newActive == mActive) {
            return;
        }
        // 立即改变活跃状态,这样就不会分发事件给非活跃 owner
        mActive = newActive;
        // mActiveCount 是 LiveData 全局变量,用于判断多少个 observer 处于活跃状态。
        // wasInactive 用于判断了上次 LiveData 是否处于非活跃状态
        boolean wasInactive = LiveData.this.mActiveCount == 0;
        LiveData.this.mActiveCount += mActive ? 1 : -1;
        if (wasInactive && mActive) {
            // 活跃 observer 数量从 0 到 1 时回调
            onActive();
        }
        if (LiveData.this.mActiveCount == 0 && !mActive) {
            // 活跃 observer 数量从 1 到 0 时回调
            onInactive();
        }
        if (mActive) {
            dispatchingValue(this);
        }
    }
}

有关dispatchingValue(ObserverWrapper)方法的源码放在 setValue(Object) 分析。

mObservers.putIfAbsent(observer, wrapper)

observe(LifecycleOwner, Observer) 方法中有一句 ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);,mObservers 是一个 SafeIterableMap 类型的映射,来看看它的部分源码:

public V putIfAbsent(@NonNull K key, @NonNull V v) {
    Entry<K, V> entry = get(key);
    if (entry != null) {
        return entry.mValue;
    }
    put(key, v);
    return null;
}

protected Entry<K, V> put(@NonNull K key, @NonNull V v) {
    Entry<K, V> newEntry = new Entry<>(key, v);
    mSize++;
    if (mEnd == null) {
        mStart = newEntry;
        mEnd = mStart;
        return newEntry;
    }
    
    mEnd.mNext = newEntry;
    newEntry.mPrevious = mEnd;
    mEnd = newEntry;
    return newEntry;
}

可以看到内部是一个非线程安全的链表存储键值对,putIfAbsent(K, V)通过 key 去查找映射内是否有对应的 value,如果存在则直接返回,不存在就放入新的数据并返回空。

observeForever(Observer)

/**
 * 和 {@link LiveData#observe(LifecycleOwner, Observer)} 类似,
 * 但是一直保持 active,意味着它会接收所有事件并且不会被自动移除。
 * 可以手动调用 {@link #removeObserver(Observer)} 来停止对 LiveData 的监听。
 * 当 LiveData 有这种 observer,将被视为 active。
 * 

* 当 observer 已经和 owner 绑定,LiveData 会抛出 {@link IllegalArgumentException} 异常。 */ @MainThread public void observeForever(@NonNull Observer<? super T> observer) { assertMainThread("observeForever"); 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); }

setValue 发送

setValue(Object) 方法

/**
 * 设置值。如果有活跃的 observer 则将值分发给它们。
 * 

* 该方法必须在主线程执行。如果需要后台执行,使用 {@link #postValue(Object)} */ @MainThread protected void setValue(T value) { assertMainThread("setValue"); mVersion++; mData = value; dispatchingValue(null); }

mVersion 变量初始值为 -1,每次 setValue(Object) 都会自增 1,相当于记录最新数据的版本。

dispatchingValue(ObserverWrapper) 方法

void dispatchingValue(@Nullable ObserverWrapper initiator) {
    // mDispatchingValue 是为了解决并发调用 dispatchingValue 的情况
    if (mDispatchingValue) {
        // mDispatchInvalidated == true 时会让下面的 while 循环再执行一次
        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;
}

该方法出现在两个地方,一个是 LifecycleOwner 生命周期发生变化时,另一个是 setValue(Object) 时。

considerNotify(ObserverWrapper) 方法

private void considerNotify(ObserverWrapper observer) {
    if (!observer.mActive) {
        return;
    }
    // 在分发之前检查最后的状态。因为有可能状态已经改变但我们还没有接收到事件。
    //
    // 我们仍然先检查 observer.active 来让它作为一个事件的入口。 
    // 所以即使 observer 变为活跃状态,如果我们还没有接收到事件,
    // 我们最好不要去通知,以便保持一个可预测的通知顺序。
    if (!observer.shouldBeActive()) {
        observer.activeStateChanged(false);
        return;
    }
    if (observer.mLastVersion >= mVersion) {
        return;
    }
    observer.mLastVersion = mVersion;
    //noinspection unchecked
    observer.mObserver.onChanged((T) mData);
}

observer 的 mLastVersion 初始值也为 -1,用于判断当前监听的数据是 LiveData 数据的哪个版本,当 mLastVersion 小于 mVersion 说明当前监听的数据不是最新,才会去回调 onChanged(Object)

通知流程

从上面的源码可以看出注册 observer 后有两种情况:

  1. 生命周期发生变化:
    1. observe(LifecycleOwner, Observer) 方法中 owner 注册了 observer
    2. owner 生命周期发生变化时调用 onStateChanged(LifecycleOwner, Lifecycle.Event)
    3. observer.activeStateChanged(boolean)
    4. dispatchingValue(ObserverWrapper),这里只传当前 observer
    5. considerNotify(ObserverWrapper),内部调用了 observer.onChanged(Object)
  2. 设置 LiveData 的数据(setValue(Object)postValue(Object)):
    1. observe(LifecycleOwner, Observer) 方法中 mObservers 映射添加了 observer
    2. setValue(Object) 时调用了 dispatchingValue(null)
    3. 对 mObservers 做循环,对每个 observer 调用 considerNotify(ObserverWrapper),内部调用了 observer.onChanged(Object)

你可能感兴趣的:(LiveData 源码解析)