深入了解架构组件LiveData

108 阅读6分钟

LiveData是Android Architecture Components中的一员,先看官方是如何介绍的:

/**
 * LiveData is a data holder class that can be observed within a given lifecycle.
 * This means that an {@link Observer} can be added in a pair with a {@link LifecycleOwner}, and
 * this observer will be notified about modifications of the wrapped data only if the paired
 * LifecycleOwner is in active state. LifecycleOwner is considered as active, if its state is
 * {@link Lifecycle.State#STARTED} or {@link Lifecycle.State#RESUMED}. An observer added via
 * {@link #observeForever(Observer)} is considered as always active and thus will be always notified
 * about modifications. For those observers, you should manually call
 * {@link #removeObserver(Observer)}.
 *
 * <p> An observer added with a Lifecycle will be automatically removed if the corresponding
 * Lifecycle moves to {@link Lifecycle.State#DESTROYED} state. This is especially useful for
 * activities and fragments where they can safely observe LiveData and not worry about leaks:
 * they will be instantly unsubscribed when they are destroyed.
 *
 * <p>
 * In addition, LiveData has {@link LiveData#onActive()} and {@link LiveData#onInactive()} methods
 * to get notified when number of active {@link Observer}s change between 0 and 1.
 * This allows LiveData to release any heavy resources when it does not have any Observers that
 * are actively observing.
 * <p>
 * This class is designed to hold individual data fields of {@link ViewModel},
 * but can also be used for sharing data between different modules in your application
 * in a decoupled fashion.
 *
 * @param <T> The type of data held by this instance
 * @see ViewModel
 */

简单来讲LiveData是一个能够感知生命周期,可观察的数据持有类,它被设计成ViewModel的一个成员变量;可以以一个更解耦的方式来共享数据。 LiveData的几个特性:

1 LiveData的实现基于观察者模式;

2 LiveData跟LifecycleOwner绑定,能感知生命周期变化,并且只会在 LifecycleOwner处于Active状态(START/RESUME)下通知数据改变;

3 LiveData会自动在DESTROYED的状态下移除Observer,取消订阅,所以不用担心内存泄漏;

LiveData的基本使用:

image.png

这就是LiveData的基本用法,接下来我们来分析源码。在分析原理前,我们带着几个问题去了解更有目的性:

1 LiveData是如何跟LifecycleOwner进行绑定的,做到感知生命周期的?

2 LiveData只在LifecycleOwner active(活跃)状态发送通知,是怎么处理的?

3 LiveData会自动在DESTORY的状态下取消订阅,是怎么处理的?

4 通过setValue()/postValue()更新数据的处理流程是怎么样的?

5 生命周期变化后数据处理流程是怎么样的?

首先来看下LiveData UML图,对LiveData有个整体的了解,后续的涉及到的类都在这里有助于理解。 f6a7fec5da0be217a817692b7ca2712.png

首先来分析LiveData.observe()开始分析:

@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
    //保证在主线程执行
    assertMainThread("observe");
    //如果是DESTROYED的状态的话,直接return 忽略掉
    if (owner.getLifecycle().getCurrentState() == DESTROYED) {
        // ignore
        return;
    }
    //把Observer用LifecycleBoundObserver包装起来
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
    //缓存起来
    ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
    //如果已经observer过并且两次的owner不同则报错
    if (existing != null && !existing.isAttachedTo(owner)) {
        throw new IllegalArgumentException("Cannot add the same observer"
                + " with different lifecycles");
    }
    //如果已经observer过
    if (existing != null) {
        return;
    }
    //绑定owner
    owner.getLifecycle().addObserver(wrapper);
}

可以看到observe方法里把我们传递的observer用LifecycleBoundObserver包装了起来,存入了mObservers,并且跟owner进行了关联。

这里有两个特殊处理:

1 忽略了处于DESTORYED的owner的注册行为。

2 将一个Observer同时绑定不同owner的行为会抛异常,也就是一个Observer只能绑定一个owner,而owner可以有多个Observer;

下面来看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() {
    //判断owner当前的状态是否至少是STARTED
        return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
    }

    @Override
    public void onStateChanged(@NonNull LifecycleOwner source,
            @NonNull Lifecycle.Event event) {
            //生命周期改变,如果是DESTORYED就自动解除
        Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
        if (currentState == DESTROYED) {
            removeObserver(mObserver);
            return;
        }
        Lifecycle.State prevState = null;
        while (prevState != currentState) {
            prevState = currentState;
            activeStateChanged(shouldBeActive());
            currentState = mOwner.getLifecycle().getCurrentState();
        }
    }

    @Override
    boolean isAttachedTo(LifecycleOwner owner) {
        return mOwner == owner;
    }

    @Override
    void detachObserver() {
        mOwner.getLifecycle().removeObserver(this);
    }
}

ObserverWrapper:

private abstract class ObserverWrapper {
    final Observer<? super T> mObserver;
    boolean mActive;
    int mLastVersion = START_VERSION;

    ObserverWrapper(Observer<? super T> observer) {
        mObserver = observer;
    }
    //是否是active状态
    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;
        changeActiveCounter(mActive ? 1 : -1);
        if (mActive) { //如果是active状态下,则发送数据更新通知
            dispatchingValue(this);
        }
    }
}

上述代码基本含义就是LifecycleBoundObserver是抽象类ObserverWrapper的子类,重写了shoulBeActive()方法,在owner处于至少是STARTED的状态下认为是active状态;并且它也实现了LifecycleEventObserver接口,可以监听lifecycle回调,并且在onStateChanged()方法里处理了生命周期改变的事件,等接收到DESTORYED的事件会自动解除跟owner的绑定,并且后续的流程就交给activeStateChanged()。

第一个问题

LiveData在observe方法中用LifecycleBoundObserver包装了observer,并且通过它绑定了owner。

第二个问题 LifecycleBoundObserver在onStateChanged()方法里处理了生命周期改变的事件,当接收到DESTORYED的事件会自动解除跟owner的绑定。

activeStateChanged(boolean)

void activeStateChanged(boolean newActive) {
    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);
    }
}

处理了onActive()和onInactive()回调的相关逻辑处理,并且调用了dispatchingValue(this)。(MediatorLiveData用到了onActive()跟onInactive(),下篇分析)

接下来分析:

dispatchingValue(ObserverWrapper)

void dispatchingValue(@Nullable ObserverWrapper initiator) {
    //如果正在分发则直接返回
    if (mDispatchingValue) {
        //标记分发失效
        mDispatchInvalidated = true;
        return;
    }
    //标记分发开始
    mDispatchingValue = true;
    do { //先执行循环体里面内容,然后再判断条件满足不,满足的话继续执行,否则不执行了。
        mDispatchInvalidated = false;
        //生命周期改变调用的方法,initiator 不为null
        if (initiator != null) {
            considerNotify(initiator);
            initiator = null;
        } else {
        //postValue/setValue方法调用传递的initiator为null
            for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                    mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                considerNotify(iterator.next().getValue());
                if (mDispatchInvalidated) {
                    break;
                }
            }
        }
    } while (mDispatchInvalidated);
    //标记分发结束
    mDispatchingValue = false;
}

considerNotify(ObserverWrapper):

private void considerNotify(ObserverWrapper observer) {
//检查状态,确保不会分发给非活跃状态的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;
    }
    //setValue会增加version,初始version为-1
    if (observer.mLastVersion >= mVersion) {
        return;
    }
    observer.mLastVersion = mVersion;
    observer.mObserver.onChanged((T) mData);
}

这里dispatchingValue正是分发事件逻辑的处理方法,而considerNotify方法则确保了只将最新的数据分发给active状态下的Observer。而且LiveData还引入了版本管理来管理数据(mData)以确保发送的数据总是最新的。

分发事件这里分两种情况: image.png

ObserverWrapper不为null

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) {
        Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
        if (currentState == DESTROYED) {
            removeObserver(mObserver);
            return;
        }
        Lifecycle.State prevState = null;
        while (prevState != currentState) {
            prevState = currentState;
            activeStateChanged(shouldBeActive());
            currentState = mOwner.getLifecycle().getCurrentState();
        }
    }

    @Override
    boolean isAttachedTo(LifecycleOwner owner) {
        return mOwner == owner;
    }

    @Override
    void detachObserver() {
        mOwner.getLifecycle().removeObserver(this);
    }
}

这LifecycleBoundObserver.onStateChanged方法里调用了activeStateChanged,而该方法调用了dispatchingValue(this),也就是LifecycleBoundObserver,这时候不为null。

这就说明生命周期改变触发的流程就是这种情况,这种情况下只会通知该Owner绑定的Observer。

ObserverWrapper为 null

@MainThread
protected void setValue(T value) {
    assertMainThread("setValue");
    mVersion++;
    mData = value;
    dispatchingValue(null);
}

这里传入的是null,这个时候的流程就会通知所有active的mObservers。

注意:LiveData对同时多次修改数据做了处理,如果同时多次修改,只会修改为最新的数据。