Android Jetpack之Lifecycle使用及源碼分析

一、前言

關(guān)于Android Jetpack是什么不在贅述,不了解的同學(xué)可以看看Android架構(gòu)木木的這篇文章Android Jetpack讓Android一飛沖天

此文章為Android Jetpack系列文章,內(nèi)容如下:
Android Jetpack之ViewModel使用及源碼分析
Android Jetpack之Lifecycle使用及源碼分析
未完待續(xù)。。。。。。

二、使用Lifecycle意義

通過Lifecycle 組件我們可以輕松的感知Activity或者Fragment的生命周期的變化。在MVP架構(gòu)中,常規(guī)的感知生命周期變化的做法,需要在BaseActicity中實(shí)現(xiàn)一個(gè)具有生命周期方法的接口,這種做法導(dǎo)致代碼的耦合性較強(qiáng),Lifecycle 的實(shí)現(xiàn)則更加優(yōu)雅。

三、使用方法

1、首先實(shí)現(xiàn)一個(gè)觀察者

public class TestLifecycleObserver implements LifecycleObserver {

    private final static String TAG = "TestLifecycleObserver";

    //注解表示此處監(jiān)聽onCreate的生命周期
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    public void onCreate() {
        Log.v(TAG, "onCreate...");
    }

    //注解表示此處監(jiān)聽onResume的生命周期
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void onResume() {
        Log.v(TAG, "onResume...");
    }

    //注解表示此處監(jiān)聽onDestroy的生命周期
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void onDestroy() {
        Log.v(TAG, "onDestroy...");
    }

}

2、在被觀察者中進(jìn)行注冊(cè)

public class MainActivity extends Activity implements LifecycleOwner {

    private LifecycleRegistry registry;
    private TestLifecycleObserver testLifecycleObserver = new TestLifecycleObserver();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
        registry.setCurrentState(Lifecycle.State.CREATED);
    }

    @Override
    protected void onResume() {
        super.onResume();
        registry.setCurrentState(Lifecycle.State.RESUMED);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        registry.setCurrentState(Lifecycle.State.DESTROYED);
        registry.removeObserver(testLifecycleObserver);
    }

    private void init() {
        registry = new LifecycleRegistry(this);
        registry.addObserver(testLifecycleObserver);
    }

    @NonNull
    @Override
    public Lifecycle getLifecycle() {
        return registry;
    }
}

看到這里有同學(xué)可能覺得,這和傳統(tǒng)的MVP方式?jīng)]有太大區(qū)別,需要實(shí)現(xiàn)LifecycleOwner接口,并且在相應(yīng)的生命周期方法里面觸發(fā)對(duì)應(yīng)的方法,所以同樣會(huì)有耦合,需要自己去控制相應(yīng)的邏輯。
事實(shí)上,在26.0.1版本后的support庫中的Activity、Fragment已經(jīng)為我們實(shí)現(xiàn)了LifecycleOwner接口,我們只需要調(diào)用addObserver添加觀察者,并且在合適的時(shí)機(jī)解注冊(cè)即可。之前的版本可以采取以上方式,自己實(shí)現(xiàn)LifecycleOwner接口,也可以實(shí)現(xiàn)生命周期變化的觀察。

四、源碼分析

同樣我們帶著問題來看代碼,通過以上的使用方法,我們可能會(huì)有如下問題:
1、LifecycleRegistry內(nèi)部是如何維護(hù)觀察者的
2、setCurrentState的時(shí)候發(fā)生了什么
3、LifecycleRegistry初始化時(shí)傳入了this參數(shù)會(huì)不會(huì)造成內(nèi)存泄漏

1、LifecycleRegistry的基本結(jié)構(gòu)

先看看LifecycleRegistry中關(guān)鍵的部分,代碼如下:

public class LifecycleRegistry extends Lifecycle {
    /**
     * 一個(gè)列表,并且可以在遍歷期間添加或者刪除元素
     * 新觀察者的狀態(tài)一定是小于等于之前的觀察者的
     */
    private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
            new FastSafeIterableMap<>();
    /**
     * 當(dāng)前狀態(tài)
     */
    private State mState;
    /**
     * 以弱引用保存LifecycleOwner,防止內(nèi)存泄漏
     */
    private final WeakReference<LifecycleOwner> mLifecycleOwner;
}

//LifecycleRegistry繼承自Lifecycle
public abstract class Lifecycle {

    @SuppressWarnings("WeakerAccess")
    public enum Event {
        ON_CREATE,
        ON_START,
        ON_RESUME,
        ON_PAUSE,
        ON_STOP,
        ON_DESTROY,
        ON_ANY
    }

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

}

由于Lifecycle用enum的形式定義了所有State,并且各個(gè)狀態(tài)是按照固定的順序來變化的,所以State具備了大小和順序的概念。LifecycleRegistry將事件通知給所有觀察者之前,存在一個(gè)同步的過程。這個(gè)同步的過程中,前面的觀察者已經(jīng)通知到了,后面的觀察者還沒被通知,于是所有觀察者之間的狀態(tài)就不一致了,各觀察者狀態(tài)之間便產(chǎn)生了大小關(guān)系,只有第一個(gè)觀察者的狀態(tài)等于最后一個(gè)觀察者的狀態(tài),并且等于LifecycleRegistry中的當(dāng)前狀態(tài)mState,才說明狀態(tài)同步整個(gè)完成了。
各個(gè)狀態(tài)的路徑變化如下圖:


20191129104813484.png

2、觀察者的注冊(cè)及保存

先來看看LifecycleRegistry的addObserver方法

    @Override
    public void addObserver(@NonNull LifecycleObserver observer) {
        //第一步
        State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
        ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
        //第二步
        ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

        if (previous != null) {
            return;
        }
        //這里持有的是LifecycleOwner的弱引用,通常是Activity
        LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
        if (lifecycleOwner == null) {
            // it is null we should be destroyed. Fallback quickly
            return;
        }
        //第三步
        boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
        State targetState = calculateTargetState(observer);
        mAddingObserverCounter++;
        while ((statefulObserver.mState.compareTo(targetState) < 0
                && mObserverMap.contains(observer))) {
            pushParentState(statefulObserver.mState);
            statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
            popParentState();
            // mState / subling may have been changed recalculate
            targetState = calculateTargetState(observer);
        }

        if (!isReentrance) {
            // we do sync only on the top level.
            sync();
        }
        mAddingObserverCounter--;
    }

大致可以分為三步:
第一步,重新包裝觀察者生成一個(gè)ObserverWithState。LifecycleObserver的關(guān)鍵的生命周期接口實(shí)現(xiàn)既可以像上面例子一樣通過@OnLifecycleEvent(XXX)注解實(shí)現(xiàn),也可以繼承相應(yīng)的接口實(shí)現(xiàn)。所以這個(gè)類的主要作用是統(tǒng)一接口回調(diào),并且保存了觀察者的狀態(tài)。
第二步,將封裝后的statefulObserver 保存進(jìn)以原始參數(shù)observer為key的map中去,同時(shí)判斷是否這個(gè)observer之前已經(jīng)添加過了,如果previous 不為null,表示之前已經(jīng)添加過了,就直接退出流程;如果lifecycleOwner 為null,說明lifecycleOwner已經(jīng)死亡了,那么也可以直接退出。順便提一句,LifecycleOwner是作為弱引用傳遞進(jìn)來的。
第三步,將新的觀察者加進(jìn)列表之后,通過while循環(huán)將它的狀態(tài)同步到最新的狀態(tài)mState。upEvent的返回值是傳入state的下一個(gè)事件,這說明新的觀察者仍然會(huì)連續(xù)收到從INITIALIZED到當(dāng)前狀態(tài)之間的所有狀態(tài),這里可以理解為是粘性的。

ObserverWithState的代碼如下:

static class ObserverWithState {
        State mState;
        LifecycleEventObserver mLifecycleObserver;

        ObserverWithState(LifecycleObserver observer, State initialState) {
            mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
            mState = initialState;
        }

        void dispatchEvent(LifecycleOwner owner, Event event) {
            State newState = getStateAfter(event);
            mState = min(mState, newState);
            mLifecycleObserver.onStateChanged(owner, event);
            mState = newState;
        }
    }

可以看到在構(gòu)造函數(shù)中調(diào)用來Lifecycling類的lifecycleEventObserver方法來封裝觀察者,這個(gè)方法就是我們前面提到的,將所有觀察者的接口適配成一致的。

再來看看觀察者的保存列表FastSafeIterableMap,其關(guān)鍵代碼如下:

public class FastSafeIterableMap<K, V> extends SafeIterableMap<K, V> {

    private HashMap<K, Entry<K, V>> mHashMap = new HashMap<>();

}

//繼承自SafeIterableMap
public class SafeIterableMap<K, V> implements Iterable<Map.Entry<K, V>> {

    @SuppressWarnings("WeakerAccess") /* synthetic access */
    Entry<K, V> mStart;
    private Entry<K, V> mEnd;
    // using WeakHashMap over List<WeakReference>, so we don't have to manually remove
    // WeakReferences that have null in them.
    private WeakHashMap<SupportRemove<K, V>, Boolean> mIterators = new WeakHashMap<>();
    private int mSize = 0;

}

我們可以得出以下結(jié)論:
1、SafeIterableMap實(shí)現(xiàn)了Iterable接口,是可以迭代的。
2、SafeIterableMap并沒有實(shí)現(xiàn)Map接口,內(nèi)部維護(hù)了一個(gè)鏈表,這樣保證了觀察者之前的時(shí)序性。同時(shí)FastSafeIterableMap中有一個(gè)HashMap,可以通過key快速查找到對(duì)應(yīng)的節(jié)點(diǎn)。
3、mStart代表頭節(jié)點(diǎn),mEnd代表尾節(jié)點(diǎn)。
4、SafeIterableMap是非線程安全的。
另外這個(gè)Map提供了三個(gè)迭代器,分別為:
1、升序迭代器AscendingIterator,迭代過程中并不包含新增的元素。
2、降序迭代器DescendingIterator,迭代過程中并不包含新增的元素。
3、迭代器IteratorWithAdditions,迭代過程中包含新增的元素。
AscendingIterator和DescendingIterator的區(qū)別在于迭代順序的不同,兩者在創(chuàng)建的一瞬間就已經(jīng)將頭節(jié)點(diǎn)和尾節(jié)點(diǎn)的指針作為參數(shù)傳入迭代器了,當(dāng)?shù)M(jìn)行到mNext == mExpectedEnd或者mExpectedEnd == null時(shí)就會(huì)結(jié)束,所以不包含后續(xù)新增的元素,具體細(xì)節(jié)可以跟跟代碼。我們可以看看AscendingIterator的創(chuàng)建過程和迭代過程的關(guān)鍵方法:

public Iterator<Map.Entry<K, V>> iterator() {
        //將當(dāng)前情況下的mStart頭節(jié)點(diǎn)和mEnd尾節(jié)點(diǎn)傳入迭代器
        ListIterator<K, V> iterator = new AscendingIterator<>(mStart, mEnd);
        mIterators.put(iterator, false);
        return iterator;
}

//迭代器AscendingIterator和DescendingIterator都是繼承自它
private abstract static class ListIterator<K, V> implements Iterator<Map.Entry<K, V>>,
            SupportRemove<K, V> {
        Entry<K, V> mExpectedEnd;
        Entry<K, V> mNext;

        ListIterator(Entry<K, V> start, Entry<K, V> expectedEnd) {
            this.mExpectedEnd = expectedEnd;
            this.mNext = start;
        }

        @Override
        public boolean hasNext() {
            return mNext != null;
        }

        @SuppressWarnings("ReferenceEquality")
        private Entry<K, V> nextNode() {
            if (mNext == mExpectedEnd || mExpectedEnd == null) {
                return null;
            }
            return forward(mNext);
        }

        @Override
        public Map.Entry<K, V> next() {
            Map.Entry<K, V> result = mNext;
            mNext = nextNode();
            return result;
        }
}

而IteratorWithAdditions則是在迭代過程中包含了新元素的,它是直接從頭節(jié)點(diǎn)一直向尾部遍歷到結(jié)束的,代碼如下:

private class IteratorWithAdditions implements Iterator<Map.Entry<K, V>>, SupportRemove<K, V> {
        private Entry<K, V> mCurrent;
        private boolean mBeforeStart = true;

        IteratorWithAdditions() {
        }

        @Override
        public boolean hasNext() {
            if (mBeforeStart) {
                return mStart != null;
            }
            return mCurrent != null && mCurrent.mNext != null;
        }

        @Override
        public Map.Entry<K, V> next() {
            if (mBeforeStart) {
                mBeforeStart = false;
                mCurrent = mStart;
            } else {
                mCurrent = mCurrent != null ? mCurrent.mNext : null;
            }
            return mCurrent;
        }
}

3、更新狀態(tài)

調(diào)用setCurrentState時(shí),真正調(diào)用的其實(shí)是moveToState方法,moveToState中的核心方法則為sync(),代碼如下:

private void sync() {
        LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
        if (lifecycleOwner == null) {
            throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
                    + "garbage collected. It is too late to change lifecycle state.");
        }
        while (!isSynced()) {
            mNewEventOccurred = false;
            // no need to check eldest for nullability, because isSynced does it for us.
            if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
                backwardPass(lifecycleOwner);
            }
            Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
            if (!mNewEventOccurred && newest != null
                    && mState.compareTo(newest.getValue().mState) > 0) {
                forwardPass(lifecycleOwner);
            }
        }
        mNewEventOccurred = false;
}

//調(diào)用isSynced()
private boolean isSynced() {
        if (mObserverMap.size() == 0) {
            return true;
        }
        State eldestObserverState = mObserverMap.eldest().getValue().mState;
        State newestObserverState = mObserverMap.newest().getValue().mState;
        return eldestObserverState == newestObserverState && mState == newestObserverState;
}

可以發(fā)現(xiàn),在進(jìn)行同步時(shí)會(huì)調(diào)用isSynced()方法,其內(nèi)部通過判斷最新和最老的觀察者的狀態(tài)是否都等于當(dāng)前狀態(tài)mState來判斷是否已經(jīng)同步完畢。狀態(tài)往INITIALIZED->RESUMED方向變化時(shí),調(diào)用forwardPass方法。狀態(tài)往RESUMED->DESTROYED方向變化時(shí),調(diào)用backwardPass方法。

forwardPass和backwardPass原理是相同的,只是方向不同,直接看forwardPass的代碼:

private void forwardPass(LifecycleOwner lifecycleOwner) {
        Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
                mObserverMap.iteratorWithAdditions();
        while (ascendingIterator.hasNext() && !mNewEventOccurred) {
            Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
            ObserverWithState observer = entry.getValue();
            while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
                    && mObserverMap.contains(entry.getKey()))) {
                pushParentState(observer.mState);
                observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
                popParentState();
            }
        }
}

這里出現(xiàn)了我們剛剛提到的迭代器。邏輯也很簡單,遍歷觀察者,逐個(gè)通知,upEvent方法的返回值是傳入state的下一個(gè)事件,這意味著每個(gè)觀察者收到的回調(diào)都是連續(xù)的。

4、對(duì)于事件嵌套的處理

通過上面的分析,可以發(fā)現(xiàn)常規(guī)情況下,有以下兩種場(chǎng)景來更新狀態(tài):
1、新觀察者注冊(cè)進(jìn)來
2、新狀態(tài)被設(shè)置進(jìn)來
考慮以下稍微復(fù)雜一些的場(chǎng)景:
1、在回調(diào)中發(fā)送了新的狀態(tài)
2、在回調(diào)中增加了新的觀察者

對(duì)于第一個(gè)場(chǎng)景,其實(shí)是通過mNewEventOccurred變量中斷當(dāng)前正在進(jìn)行的同步,并且以新的狀態(tài)同步。

對(duì)于第二個(gè)場(chǎng)景,在添加新的觀察者時(shí),有如下代碼:

private State calculateTargetState(LifecycleObserver observer) {
        Entry<LifecycleObserver, ObserverWithState> previous = mObserverMap.ceil(observer);

        State siblingState = previous != null ? previous.getValue().mState : null;
        State parentState = !mParentStates.isEmpty() ? mParentStates.get(mParentStates.size() - 1)
                : null;
        return min(min(mState, siblingState), parentState);
}

parentState的賦值是在執(zhí)行觀察者的回調(diào)前,先將觀察者當(dāng)前狀態(tài)pushParentState壓入棧,在回調(diào)結(jié)束之后,popParentState出棧。
previous表示新的觀察者前面的那個(gè)觀察者,也就是原來的觀察隊(duì)列的隊(duì)尾,而現(xiàn)在的隊(duì)尾是新觀察者了。可以看出State是取LifecycleRegistry當(dāng)前狀態(tài),previous當(dāng)前狀態(tài),parentState棧頂狀態(tài)三者的最小值。這樣就保證了新的觀察者的狀態(tài)不會(huì)大于之前的觀察者的狀態(tài)。

4、觀察者的解注冊(cè)

觀察者解注冊(cè)的邏輯比較簡單,代碼如下:

@Override
public void removeObserver(@NonNull LifecycleObserver observer) {
        mObserverMap.remove(observer);
}

至此,整個(gè)源碼分析過程結(jié)束。

最后編輯于
?著作權(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),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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