帶你深入了解官方架構(gòu)組件LiveData

本文只分析 Livedata 好處、原理實(shí)現(xiàn),用法用處不再贅述(官網(wǎng)啥都有 ??)。
官方文檔連接(需翻墻)

一、LiveData 介紹

Livedata 是 Google 推薦的 Android 架構(gòu)組件之一,是一個(gè)存放可被觀察的數(shù)據(jù)持有類(lèi),但與一般的被觀察者不同的是,它是有生命周期感知功能,解決了android開(kāi)發(fā)者需要去手動(dòng)處理生命周期的痛點(diǎn)。
比如之前用 Retrofit+Rxjava處理接口回調(diào)數(shù)據(jù),需要自己去處理 activity 或 fragment 生命周期,以解決 onStop 或 onDestory之后回調(diào)數(shù)據(jù)的問(wèn)題?,F(xiàn)在只需要 Retrofit+Livedata 就好,其他的 Livedata 幫你做了。

二、Livedata 優(yōu)點(diǎn)

英文水平有限,避免誤人我還是把官網(wǎng)原文搬過(guò)來(lái)一下吧。
以下是看完官網(wǎng)后的個(gè)人理解,并不是完全的翻譯。

1、Ensures your UI matches your data state(不知道怎么翻譯):

LiveData follows the observer pattern. LiveData notifies Observer objects when the lifecycle state changes. You can consolidate your code to update the UI in these Observer objects. Instead of updating the UI every time the app data changes, your observer can update the UI every time there's a change.
Livedata 遵循觀察者模式,并且 Livedata 會(huì)在生命周期變化的時(shí)候通知觀察者。
它優(yōu)雅的處理了生命周期問(wèn)題,并不會(huì)所有的數(shù)據(jù)變化都會(huì)回調(diào),所以你可以在他回調(diào)時(shí)大膽的做更新 UI操作。

2、No memory leaks(沒(méi)有內(nèi)存泄漏):

Observers are bound to Lifecycle objects and clean up after themselves when their associated lifecycle is destroyed.
觀察者都是綁定Lifecycle的, Lifecycle destory 的話(huà),會(huì)銷(xiāo)毀自己。

Lifecycle也是架構(gòu)組件之一,了解請(qǐng)看我的另一篇專(zhuān)門(mén)介紹連接

3、No crashes due to stopped activities(activity stop之后,不會(huì)崩潰)

If the observer's lifecycle is inactive, such as in the case of an activity in the back stack, then it doesn’t receive any LiveData events.
Livedata 把 activity 生命周期合并分成了inactive與active兩種狀態(tài)(start 與 resume 為 active,其他為inactive)。處于非活 inactive 狀態(tài)的話(huà),是不會(huì)收到 Livedata 任何事件的。

4、No more manual lifecycle handling(不需要手動(dòng)管理生命周期):

UI components just observe relevant data and don’t stop or resume observation. LiveData automatically manages all of this since it’s aware of the relevant lifecycle status changes while observing.
UI 組件只需要關(guān)心相關(guān)的數(shù)據(jù),不需要去手動(dòng)變換生命周期狀態(tài),Livedata 已經(jīng)幫你搞定了。

5、Always up to date data():

If a lifecycle becomes inactive, it receives the latest data upon becoming active again. For example, an activity that was in the background receives the latest data right after it returns to the foreground.
簡(jiǎn)單來(lái)說(shuō),Livedata 在生命周期非活狀態(tài)inactive,數(shù)據(jù)發(fā)生變化的話(huà),變成活狀態(tài)active的時(shí)候,會(huì)回調(diào)一次最終的數(shù)據(jù)。

6、Proper configuration changes:

If an activity or fragment is recreated due to a configuration change, like device rotation, it immediately receives the latest available data.
像屏幕旋轉(zhuǎn)導(dǎo)致的 activity 或 fragment重創(chuàng)建之后,Livedata 會(huì)立即通知一下相應(yīng)的觀察者。保證了數(shù)據(jù)不會(huì)丟失。

7、Sharing resources

You can extend a LiveData object using the singleton pattern to wrap system services so that they can be shared in your app. The LiveData object connects to the system service once, and then any observer that needs the resource can just watch the LiveData object. For more information, see Extend LiveData.
這個(gè)怎么說(shuō)呢

三、Livedata 如何實(shí)現(xiàn)這些功能,源碼分析

又到了大家最喜歡的 Read the fucking source code 環(huán)節(jié)。好找在Livedata 源碼不多,而且容易理解

1、如何做到生命周期感知:

這里涉及到LifecycleOwner屬于另一個(gè)架構(gòu)組件 lifecycle,可參考我的另一篇lifecycle專(zhuān)講。
不了解的話(huà)也沒(méi)關(guān)系,只需要知道lifecycle可以提供activity 或 fragment 當(dāng)前的生命周期狀態(tài),并且狀態(tài)是可以被觀察的。

首先從Livedata添加觀察者的方法 observe 開(kāi)始:

    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        LifecycleBoundObserver existing = mObservers.putIfAbsent(observer, wrapper);
        if (existing != null && existing.owner != wrapper.owner) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if (existing != null) {
            return;
        }
        owner.getLifecycle().addObserver(wrapper);
    }

第一個(gè)參數(shù)為L(zhǎng)ifecycleOwner用于提供當(dāng)前的生命周期狀態(tài),DESTROYED的時(shí)候不做任何操作。
第二個(gè)為觀察者observer,首先把observer包裝成了LifecycleBoundObserver這是一個(gè)一會(huì)分析。然后把LifecycleBoundObserver維護(hù)到mObservers里:

private SafeIterableMap<Observer<T>, LifecycleBoundObserver> mObservers =
            new SafeIterableMap<>();

mObservers是一個(gè)LinkedList結(jié)構(gòu)的容器 通過(guò)putIfAbsent方法判斷,容器中此觀察者是不是已經(jīng)存在,如果存在且LifecycleOwner不同的話(huà)則拋異常,LifecycleOwner相同則 return 不重復(fù)添加。
wrapper 也就是LifecycleBoundObserver實(shí)現(xiàn)了LifecycleObserver是 lifecycle 的觀察者所以最后添加到 lifecycle 的觀察中。

再來(lái)揭曉L(fǎng)ifecycleBoundObserver:

    class LifecycleBoundObserver implements GenericLifecycleObserver {
        public final LifecycleOwner owner;
        public final Observer<T> observer;
        public boolean active;
        public int lastVersion = START_VERSION;

        LifecycleBoundObserver(LifecycleOwner owner, Observer<T> observer) {
            this.owner = owner;
            this.observer = observer;
        }

        @Override
        public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
            if (owner.getLifecycle().getCurrentState() == DESTROYED) {
                removeObserver(observer);
                return;
            }
            // immediately set active state, so we'd never dispatch anything to inactive
            // owner
            activeStateChanged(isActiveState(owner.getLifecycle().getCurrentState()));
        }

        void activeStateChanged(boolean newActive) {
            if (newActive == active) {
                return;
            }
            active = newActive;
            boolean wasInactive = LiveData.this.mActiveCount == 0;
            LiveData.this.mActiveCount += active ? 1 : -1;
            if (wasInactive && active) {
                onActive();
            }
            if (LiveData.this.mActiveCount == 0 && !active) {
                onInactive();
            }
            if (active) {
                dispatchingValue(this);
            }
        }
    }

答案就在這里

此類(lèi)實(shí)現(xiàn)了GenericLifecycleObserver 即 為lifecycle 的觀察者,通過(guò)上文的 observe方法添加到了lifecycle觀察中,
通過(guò)此類(lèi)持有 Livedata 的觀察者observer,當(dāng) 生命周期發(fā)生變化時(shí) 會(huì)回調(diào)onStateChanged方法,然后 Livedata 的觀察者在onStateChanged中執(zhí)行相應(yīng)的邏輯。

再來(lái)看onStateChanged具體邏輯:
第一個(gè)判斷就搞定了 二、2、No memory leaks(沒(méi)有內(nèi)存泄漏)功能點(diǎn):如果生命周期是 destory 的話(huà),移除觀察者。

然后通過(guò)isActiveState方法,把所有生命周期劃分成兩類(lèi) inactive 與 active

 static boolean isActiveState(State state) {
        return state.isAtLeast(STARTED);
    }

State為枚舉:

public enum State {
  DESTROYED,
  INITIALIZED,
  CREATED,
  STARTED,
  RESUMED;
  public boolean isAtLeast(@NonNull State state) {
         return compareTo(state) >= 0;
  }
}

通過(guò)compareTo方法 isAtLeast為 true 的話(huà)至少是STARTED或RESUMED。

接著執(zhí)行activeStateChanged

       void activeStateChanged(boolean newActive) {
            if (newActive == active) {
                return;
            }
            active = newActive;
            boolean wasInactive = LiveData.this.mActiveCount == 0;
            LiveData.this.mActiveCount += active ? 1 : -1;
            if (wasInactive && active) {
                onActive();
            }
            if (LiveData.this.mActiveCount == 0 && !active) {
                onInactive();
            }
            if (active) {
                dispatchingValue(this);
            }
        }

通過(guò)巧妙的設(shè)計(jì)實(shí)現(xiàn)了:
1、狀態(tài)沒(méi)有變化,什么也不做。
2、變?yōu)榛睿╝ctive)就是調(diào)用onActive(),非活(inactive)就調(diào)用onInactive().
3、另外,變?yōu)榛畹脑?huà)就調(diào)用dispatchingValue方法,此方法為回調(diào)觀察者的方法。即 二、5、Always up to date data,非活變?yōu)榛?,?huì)立即回調(diào)一次數(shù)據(jù)(如果數(shù)據(jù)發(fā)生變化的話(huà)情況下)。

2、事件的通知

LiveData通過(guò) setValue 或 postValue 方法去改變持有的數(shù)據(jù),并通知觀察者,最終都是調(diào)用dispatchingValue()方法:

    private void dispatchingValue(@Nullable LifecycleBoundObserver initiator) {
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            if (initiator != null) {
                considerNotify(initiator);
                initiator = null;
            } else {
                for (Iterator<Map.Entry<Observer<T>, LifecycleBoundObserver>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }

這一些列的判斷 ,目前我還沒(méi)有領(lǐng)悟是為了什么?。。?br> 最終通過(guò)調(diào)用considerNotify:

    private void considerNotify(LifecycleBoundObserver observer) {
        if (!observer.active) {
            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 (!isActiveState(observer.owner.getLifecycle().getCurrentState())) {
            observer.activeStateChanged(false);
            return;
        }
        if (observer.lastVersion >= mVersion) {
            return;
        }
        observer.lastVersion = mVersion;
        //noinspection unchecked
        observer.observer.onChanged((T) mData);
    }

代碼很簡(jiǎn)單,先判斷下,最終的數(shù)據(jù)有沒(méi)有通知過(guò),沒(méi)有的話(huà)直接 observer。

分析完畢!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容