Jetpack-LiveData源码解析

LiveData源码解析

源码版本:2.4.0
需会使用:Lifecycle

导航:

使用

监听值

liveData.observe(LifecycleOwner, Observer)
liveData.observeForever(Observer)

设置值

liveData.setValue(value)
liveData.postValue(value)

移除监听

liveData.removeObserver(Observer)
liveData.removeObservers(LifecycleOwner)

源码

构造函数

// 有默认值
public LiveData(T value) {
    mData = value;
    // 版本号加1,以标记此LivaData的数据版本要比观察者包装者的数据版本要高(新),以进行通知观察者Observer。
    mVersion = START_VERSION + 1;
}

// 无默认值
public LiveData() {
    mData = NOT_SET;
    // 版本号和观察者包装者的版本相同,以不进行通知观察者Observer。
    mVersion = START_VERSION;
}

监听值

observe

LiveData --> observe方法

@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
    // 断言只能在主线程调用,否则抛异常。
    assertMainThread("observe");
    // 当Lifecycle处于DESTROYED状态时,再观察是没有意义的,直接返回。
    if (owner.getLifecycle().getCurrentState() == DESTROYED) {
        // ignore
        return;
    }
    // 创建新的Observer包装者LifecycleBoundObserver,让其监听生周周期变化,并处理。
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
    // mObservers是一个Map,key为Observer,value为ObserverWrapper,持有多个观察者包装者。
    // putIfAbsent,如果传入key对应的value已经存在,就返回存在的value,不进行替换。如果不存在,就添加key和value,并返回null。
    ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
    if (existing != null && !existing.isAttachedTo(owner)) {
        // 该Observer对象已经被该LiveData持有,且该值ObserverWrapper对象没依附于当前的Lifecycle对象,说明该值ObserverWrapper之前已经被其它的Lifecycle对象添加,再被当前的Lifecycle添加,则直接抛出异常。
        throw new IllegalArgumentException("Cannot add the same observer"
                + " with different lifecycles");
    }
    if (existing != null) {
        // 该Observer对象已经被该LiveData持有,且该值ObserverWrapper对象依附于当前的Lifecycle对象,说明该值ObserverWrapper之前已经被当前的Lifecycle对象添加,则直接返回。
        return;
    }
    // 使用Lifecycle控件,观察该ObserverWrapper对象生命周期。
    owner.getLifecycle().addObserver(wrapper);
}

说明:

  1. 必须在主线程调用observe方法。
  2. 同一个LiveData,同一个Observerobserve方法不能用不同的Lifecycle

observe方法就是把我们的Observer对象包装成LifecycleBoundObserver后存入mObservers中,并将其添加到Lifecycle中,以监听生命周期变化。它继承ObserverWrapper并实现了LifecycleEventObserver

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();

    // 此观察者包装者,是否依附到LifecycleOwner的Lifecycle组件中。
    boolean isAttachedTo(LifecycleOwner owner) {
        return false;
    }

    // 此观察者包装者,分离Observer,即不再观察此ObserverWrapper。
    void detachObserver() {
    }

    // 此观察者包装者,活跃状态改变。
    void activeStateChanged(boolean newActive) {
        if (newActive == mActive) {
            // 新状态和现有状态相同,则不处理。
            return;
        }
        // 记录活跃状态
        mActive = newActive;
        // 改变活跃观察者的数量,此观察者包装者,变活跃+1,变非活跃-1。
        changeActiveCounter(mActive ? 1 : -1);
        if (mActive) {
            // 活跃状态下,进行分发值。
            dispatchingValue(this);
        }
    }
}

然后我们再看被Lifecycle添加的,生命周期可感知的LifecycleBoundObserver类。

LifecycleBoundObserver类

class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
    // 传入的Lifecycle持有者对象
    @NonNull
    final LifecycleOwner mOwner;

    LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
        super(observer);
        mOwner = owner;
    }

    // 此观察者包装者,是否应该处于活跃状态。
    @Override
    boolean shouldBeActive() {
        // onStart,onResume,onPause这三个状态处于活跃状态,其它处于非活跃状态。
        return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
    }
    
    // LifecycleEventObserver接口实现方法,生命周期状态改变的时候调用。
    @Override
    public void onStateChanged(@NonNull LifecycleOwner source,
            @NonNull Lifecycle.Event event) {
        Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
        if (currentState == DESTROYED) {
            // 当生命周期状态为destroyed的时候,把该观察者移除。
            // 然后在removeObserver内部,会调用detachObserver方法,将此ObserverWrapper从Lifecycle中移除。并调用activeStateChanged方法,通知活跃状态改为:非活跃的。
            removeObserver(mObserver);
            return;
        }
        // 生命周期状态改变,通知活跃状态改变。
        // 加While循环的目的,防止执行activeStateChanged的时候,mOwner的生命周期的状态更改。
        Lifecycle.State prevState = null;
        while (prevState != currentState) {
            prevState = currentState;
            // 通知活跃状态改变
            activeStateChanged(shouldBeActive());
            currentState = mOwner.getLifecycle().getCurrentState();
        }
    }

    // 此观察者包装者,是否依附到LifecycleOwner的Lifecycle组件中。
    @Override
    boolean isAttachedTo(LifecycleOwner owner) {
        // 如果持有的(传入的)mOwner与要比较的owner相同,则认为此观察者包装者,是依附到传入的Lifecycle组件中。
        return mOwner == owner;
    }

    // 此观察者包装者,分离Observer,即不再观察此ObserverWrapper。
    @Override
    void detachObserver() {
        // Lifecycle移除此ObserverWrapper
        mOwner.getLifecycle().removeObserver(this);
    }
}

LiveData --> removeObserver方法

@MainThread
public void removeObserver(@NonNull final Observer<? super T> observer) {
    // 断言只能在主线程调用,否则抛异常。
    assertMainThread("removeObserver");
    // 将observer从mObservers中移除
    ObserverWrapper removed = mObservers.remove(observer);
    if (removed == null) {
        // removed为空,则代表observer就没有被mObservers添加,直接返回。
        return;
    }
    // 被移除的观察者包装者,不再观察ObserverWrapper。
    removed.detachObserver();
    // 被移除的观察者包装者,通知活跃状态改为:非活跃的。
    removed.activeStateChanged(false);
}

代码流程:

  1. observe方法将LifecycleBoundObserver添加到mObservers,并添加到Lifecycle观察。
  2. 当生命周期状态改变的时候,通知LifecycleBoundObserveronStateChanged方法。
  3. 当生命周期状态改变为destroyed的时候,会调用detachObserver方法,将此ObserverWrapperLifecycle中移除。并调用activeStateChanged方法,通知活跃状态为:非活跃的。
  4. 当生命周期状态改变为其它的时候,会调用activeStateChanged方法,通知活跃状态为:onStartonResumeonPause活跃的,其它为非活跃的
  5. activeStateChanged方法,会过滤相同的状态。并调用changeActiveCounter方法,改变活跃观察者的数量,以及如果是活跃状态,则调用dispatchingValue方法,进行分发值。

说明:

  1. LiveData.observe(LifecycleOwner, Observer),传入的Observer,不需要手动移除,它会在生命周期状态为DESTROYED的时候,自动移除。
  2. onStartonResumeonPause活跃状态,其它为非活跃状态非活跃状态下,不进行分发值
  3. 非活跃状态下,设置的值,直到生命周期状态改变活跃状态,就会将值进行分发,所以LiveData自带粘性事件特征。

接下来,我们来看一个changeActiveCounter方法,改变活跃观察者的数量。

LiveData --> changeActiveCounter方法

@MainThread
void changeActiveCounter(int change) {
    // 记录之前活跃的数量
    int previousActiveCount = mActiveCount;
    // 记录现在的活跃的数量,change:活跃状态为+1,非活跃状态为-1。
    mActiveCount += change;
    if (mChangingActiveState) {
        // 如果是改变中,则返回。
        return;
    }
    // 标记为改变中
    mChangingActiveState = true;
    try {
         // 之前的活跃数量和现在的活跃数量不一致,那么将执行下面的通知变活跃/变非活跃逻辑。
         // 加while的原因,因为当执行下面判断逻辑的时候,changeActiveCounter方法再次调用,导致mActiveCount值更改,所以加while使其保持一致。
        while (previousActiveCount != mActiveCount) {
            // 之前的活跃数量为0,并且现在的活跃数量大于0,即说明之前是非活跃状态,然后现在是活跃状态,则需要调用变活跃方法。
            boolean needToCallActive = previousActiveCount == 0 && mActiveCount > 0;
            // 之前的活跃数量是大于0,并且现在的活跃数量为0,即说明之前是活跃状态,然后现在是非活跃状态,则需要调用变非活跃方法。
            boolean needToCallInactive = previousActiveCount > 0 && mActiveCount == 0;
            // 让previousActiveCount和mActiveCount保持一致
            previousActiveCount = mActiveCount;
            if (needToCallActive) {
                // 需要调用变活跃方法,它是空方法,可以自定义LiveData实现。
                onActive();
            } else if (needToCallInactive) {
                // 需要调用变非活跃方法,它是空方法,可以自定义LiveData实现。
                onInactive();
            }
        }
    } finally {
        // 标记为改变结束
        mChangingActiveState = false;
    }
}

LiveData --> dispatchingValue方法

void dispatchingValue(@Nullable ObserverWrapper initiator) {
    if (mDispatchingValue) {
        // 分发值中,则标记分发失效的。
        mDispatchInvalidated = true;
        return;
    }
    // 标记分发值中
    mDispatchingValue = true;
    do {
        // 清空分发失效的标记
        mDispatchInvalidated = false;
        if (initiator != null) {
            // initiator不为空,为活跃状态变化传入的ObserverWrapper,则直接通知该ObserverWrapper。
            // 考虑通知
            considerNotify(initiator);
            // 直接清空标记
            initiator = null;
        } else {
            // initiator为空,为setValue()调用,则通知所有的ObserverWrapper。
            for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                    mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                // 考虑通知
                considerNotify(iterator.next().getValue());
                // 在遍历过程中,如果遇到值更新(dispatchingValue调用),则立即退出当前分发,
                // 则继续走while,再执行 do 中逻辑。
                if (mDispatchInvalidated) {
                    break;
                }
            }
        }
    } while (mDispatchInvalidated);
    // 标记分发值结束
    mDispatchingValue = false;
}

LiveData --> considerNotify方法

@SuppressWarnings("unchecked")
private void considerNotify(ObserverWrapper observer) {
    if (!observer.mActive) {
        // 非活跃状态,则不进行后续处理。
        return;
    }
    if (!observer.shouldBeActive()) {
        // mActive为活跃状态,shouldBeActive()为非活跃状态,则以shouldBeActive()状态为主,同步状态,不进行后续处理。
        observer.activeStateChanged(false);
        return;
    }
    if (observer.mLastVersion >= mVersion) {
        // observer数据的版本[大于等于]当前LiveData数据的版本,则说明数据已经同步,则不进行后续处理。
        return;
    }
    // 观察者包装者,更新版本。
    observer.mLastVersion = mVersion;
    // 观察者包装者,通知传入的观察者,数据改变。
    observer.mObserver.onChanged((T) mData);
}

代码流程:

  1. activeStateChanged方法,调用changeActiveCounter方法更改活跃观察者的数量,并通知LiveData变活跃/变非活跃
  2. activeStateChanged方法,如果是活跃状态,则调用dispatchingValue方法,进行分发值。
  3. dispatchingValue方法,如果是活跃状态改变而分发值,则直接让此ObserverWrapper考虑通知(调用considerNotify方法)。如果是setValue()而分发值,则让所有的ObserverWrapper考虑通知。
  4. considerNotify方法,会进行最终的判断,如果是活跃的,并且ObserverWrapper的数据版本过老,则进行通知。

observeForever

@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
    // 断言只能在主线程调用,否则抛异常。
    assertMainThread("observeForever");
    // 创建新的Observer包装者AlwaysActiveObserver,让其处理。
    AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
    ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
    if (existing instanceof LiveData.LifecycleBoundObserver) {
        // 该Observer对象已经被该LiveData持有,且该ObserverWrapper是LifecycleBoundObserver对象,说明该Observer已经被Lifecycle观察,再被Forever观察,则直接抛出异常。
        throw new IllegalArgumentException("Cannot add the same observer"
                + " with different lifecycles");
    }
    if (existing != null) {
        // 该Observer对象已经被该LiveData持有,且该ObserverWrapper是非LifecycleBoundObserver对象,说明该Observer已经被Forever观察,再被Forever观察,则直接返回。
        return;
    }
    // 立即通知活跃状态为:活跃的。
    wrapper.activeStateChanged(true);
}

说明:

  1. 必须在主线程调用observeForever方法。
  2. 同一个LiveData,同一个Observerobserve方法、observeForever方法不能用同一个Observer

observeForever方法就是把我们的Observer对象包装成AlwaysActiveObserver后存入mObservers中,并立即通知活跃状态为:活跃的

LifecycleBoundObserver类

private class AlwaysActiveObserver extends ObserverWrapper {

    AlwaysActiveObserver(Observer<? super T> observer) {
        super(observer);
    }

    // 此观察者包装者,是否应该处于活跃状态。
    @Override
    boolean shouldBeActive() {
        // 始终处于活跃状态,此方法只在shouldBeActive方法内调用。
        return true;
    }
}

代码流程:

  1. observeForever方法,将观察者包装者AlwaysActiveObserver添加到mObservers,并立即调用activeStateChanged方法,通知活跃状态为:活跃的
  2. activeStateChanged方法,活跃状态下,会调用dispatchingValue方法,进行分发值。
  3. dispatchingValue方法,则直接让此ObserverWrapper考虑通知(调用considerNotify方法)。
  4. considerNotify方法,会进行最终的判断,如果是活跃的,并且ObserverWrapper的数据版本过老,则进行通知。

说明:

  1. LiveData.observeForever(Observer),传入的Observer,需要手动移除。

设置值

setValue

@MainThread
protected void setValue(T value) {
    // 断言只能在主线程调用,否则抛异常。
    assertMainThread("setValue");
    // 当前LiveData数据的版本,每次有新值版本都会+1,用于和观察者包装者的版本进行比较,如果观察者包装者的版本小于此值,则进行通知更新。
    mVersion++;
    // 记录需要分发的值
    mData = value;
    // 进行分发值,传null代表考虑分发给所有的观察者包装者。
    dispatchingValue(null);
}

postValue

protected void postValue(T value) {
    // 是否要发送任务
    boolean postTask;
    // 加synchronized,防止并发,保证线程安全。
    synchronized (mDataLock) {
        // 是否要发送,如果mPendingData != NOT_SET,即上一次的post没有执行完,再发送新值,则不再发送。
        postTask = mPendingData == NOT_SET;
        // 记录要待处理的数据
        mPendingData = value;
    }
    if (!postTask) {
        // 不发送,直接返回。
        return;
    }
    // 使用Handler,post到主线程,设置值。
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
private final Runnable mPostValueRunnable = new Runnable() {
    @SuppressWarnings("unchecked")
    @Override
    public void run() {
        // 记录新值,防止mPendingData更改
        Object newValue;
        // 加synchronized,防止并发,保证线程安全。
        synchronized (mDataLock) {
            // 记录新值
            newValue = mPendingData;
            // mPendingData重置,标记执行完成。
            mPendingData = NOT_SET;
        }
        // 调用setValue,设置新值。
        setValue((T) newValue);
    }
};

代码流程:

  1. setValue方法,会调用dispatchingValue方法,进行分发值。
  2. dispatchingValue方法,让全部ObserverWrapper考虑通知(调用considerNotify方法)。
  3. considerNotify方法,会进行最终的判断,如果是活跃的,并且ObserverWrapper的数据版本过老,则进行通知。

说明:

  1. postValue方法,也是调用的setValue方法。

移除监听

removeObserver

移除单个Observer

@MainThread
public void removeObserver(@NonNull final Observer<? super T> observer) {
    // 断言只能在主线程调用,否则抛异常。
    assertMainThread("removeObserver");
    // 将observer从mObservers中移除
    ObserverWrapper removed = mObservers.remove(observer);
    if (removed == null) {
        // removed为空,则代表observer就没有被mObservers添加,直接返回。
        return;
    }
    // 被移除的观察者包装者,不再观察ObserverWrapper。
    removed.detachObserver();
    // 被移除的观察者包装者,通知活跃状态改为:非活跃的。
    removed.activeStateChanged(false);
}

removeObservers

移除LifecycleOwner所属的所有Observer

@SuppressWarnings("WeakerAccess")
@MainThread
public void removeObservers(@NonNull final LifecycleOwner owner) {
    // 断言只能在主线程调用,否则抛异常。
    assertMainThread("removeObservers");
    for (Map.Entry<Observer<? super T>, ObserverWrapper> entry : mObservers) {
        if (entry.getValue().isAttachedTo(owner)) {
            // 只有所属于LifecycleOwner的才会移除,如observeForever添加的不会移除。
            removeObserver(entry.getKey());
        }
    }
}

总结

以上就是全面的Jetpack-LiveData源码了!之后会出Jetpack其它源码系列,请及时关注。如果你有什么问题,大家评论区见!

最后推荐一下我的网站,开发者的技术博客: devbolg.cn ,目前包含android相关的技术,之后会面向全部开发者,欢迎大家来体验!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容