Jetpack - LiveData入门 看这一篇就够了

170 阅读2分钟

一、优点:

  1. LiveData 可以很大程度上避免内存泄漏;

  2. 更好的将View层与Model层分离。

二、常用方法

LiveData是基于观察者机制实现的,LiveData是被观察者,Observer是观察者,

当LiveData有数据变化时会通知他的观察者去更新数据。

常用方法如下:

  • setValue

  • postValue

  • observe

  • observeForever

三、setValue

setValue 跟 postValue 都是用来修改LiveData值的。

「setValue 源码」

@MainThread

protected void setValue(T value) {

    assertMainThread("setValue");

    mVersion++;

    mData = value;

    dispatchingValue(null);

}

Tips:
  1. MainThread表示setValue只能在主线程中调用,

  2. assertMainThread("setValue")判断当前调用是否在主线程中,如果不是会抛异常。

  3. mVersion++ 用于记录LiveData是否有更新,每更新一次,mVersion都加一;

  4. dispatchingValue(null) 用于通知观察者更新数据

// 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;
    }
}
Tips

dispatchingValue(@Nullbale ObserverWrapper initiator)

传入的参数是观察者,如果非空,则只通知这个观察者进行数据更新,否则会遍历该LiveData下所有的观察者,并一一通知更新。

上述代码中真正通知观察者去进行数据更新的是considerNotify()方法

/**
 *1、「observer.mActive」 判断观察者是否处于活跃状态
 *2、「observer.shouldBeActivie」 判断所在页面是否处于活跃状态(比如观察者所在页面已进入   onDestroy函数,则页面就是非活跃状态),如果页面不处于活跃状态,则需要把观察者自身状态修改为   非活跃状态
 *3、活跃状态下,观察者自身的「mLastVersion」与LiveData的「mVersion」对比,若mLastVersion   >= mVersion 表示没有更新
 *4、最后,有更新情况下,观察者修改自身mLastVersion,并调用onChanged做数据更新
 */

private void considerNotify(ObserverWrapper observer) {
    if (!observer.mActive) {
        return;
    }
    if (!observer.shouldBeActive()) {
        observer.activeStateChanged(false);
        return;
    }
    if (observer.mLastVersion >= mVersion) {
        return;
    }
    observer.mLastVersion = mVersion;
    observer.mObserver.onChanged((T) mData);
}

四、postValue

「postValue」与「setValue」区别是:

setValue只能在主线程中调用,而postValue可以在任意线程中调用。

同时,postValue内部最终还是通过setValue来实现数据更新的。

还有一点,多次调用postValue,只有最后一次调用时传入的值有效。

postValue源码如下
static final Object NOT_SET = new Object();
volatile Object mPendingData = NOT_SET;

protected void postValue(T value) {
    boolean postTask;
    synchronized (mDataLock) {
        postTask = mPendingData == NOT_SET;
        mPendingData = value;
    }
    if (!postTask) {
        return;
    }
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}

private final Runnable mPostValueRunnable = new Runnable() {
    @SuppressWarnings("unchecked")
    @Override
    public void run() {
        Object newValue;
        synchronized (mDataLock) {
            newValue = mPendingData;
            mPendingData = NOT_SET;
        }
        setValue((T) newValue);
    }
};

observer.shouldBeActive()

LiveData中的两种观察者

* LifecycleBoundObserver

LifecycleBoundObserver中的shouldBeActive方法,会判断页面至少要处于started状态才认为是处于活跃状态,

正因为shouldBeActivie方法的实现,才使得LiveData具有可以避免内存泄漏的能力。

LifecycleBoundObserver源码

class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {

......
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
......
}

public enum State {
    // onDestroy()
    DESTROYED,
    INITIALIZED,
    // 介于 onCreate() -- onStop() 之间
    CREATED,
    // 介于 onStart() -- onPause() 之间
    STARTED,
    // onResume()
    RESUMED;
    public boolean isAtLeast(@NonNull State state) {
    }
}

* AlwaysActiveObserver