1. 程式人生 > >硬核講解 Jetpack 之 LifeCycle 原始碼篇

硬核講解 Jetpack 之 LifeCycle 原始碼篇

前一篇 硬核講解 Jetpack 之 LifeCycle 使用篇 主要介紹了 LifeCycle 存在的意義,基本和進階的使用方法。今天話不多說,直接開始擼原始碼。

本文基於我手裡的 android_9.0.0_r45 原始碼,所有相關原始碼包括註釋都上傳到了我的 Github ,可以直接 clone 下來對照文章檢視。

LifeCycle 三劍客

在正式閱讀原始碼之前,很有必要先介紹幾個名詞,LifecycleOwner ,LifecycleObserver,Lifecycle 。

LifecycleOwner 是一個介面 , 介面通常用來宣告具備某種能力。LifecycleOwner 的能力就是具有生命週期。典型的生命週期元件有 Activity

Fragment 。當然,我們也可以自定義生命週期元件。LifecycleOwner 提供了 getLifecycle() 方法來獲取其 Lifecycle 物件。

public interface LifecycleOwner {

    @NonNull
    Lifecycle getLifecycle();
}

LifecycleObserver 是生命週期觀察者,它是一個空介面。它沒有任何方法,依賴 OnLifecycleEvent 註解來接收生命週期回撥。

public interface LifecycleObserver {

}

生命週期元件 和 生命週期觀察者 都有了,Lifecycle

就是它們之間的橋樑。

Lifecycle 是具體的生命週期物件,每個 LifecycleOwner 都會持有 Lifecycle 。通過 Lifecycle 我們可以獲取當前生命週期狀態,新增/刪除 生命週期觀察者等等。

Lifecycle 內部定義了兩個列舉類,EventStateEvent 表示生命週期事件,與 LifecycleOwner 的生命週期事件是相對應的。

public enum Event {
    /**
     * Constant for onCreate event of the {@link LifecycleOwner}.
     */
    ON_CREATE,
    /**
     * Constant for onStart event of the {@link LifecycleOwner}.
     */
    ON_START,
    /**
     * Constant for onResume event of the {@link LifecycleOwner}.
     */
    ON_RESUME,
    /**
     * Constant for onPause event of the {@link LifecycleOwner}.
     */
    ON_PAUSE,
    /**
     * Constant for onStop event of the {@link LifecycleOwner}.
     */
    ON_STOP,
    /**
     * Constant for onDestroy event of the {@link LifecycleOwner}.
     */
    ON_DESTROY,
    /**
     * An {@link Event Event} constant that can be used to match all events.
     */
    ON_ANY
}

ON_ANY 比較特殊,它表示任意生命週期事件。為什麼要設計 ON_ANY 呢?其實我也不知道,暫時還沒發現它的用處。

另一個列舉類 State 表示生命週期狀態。

public enum State {
        /**
         * 在此之後,Lifecycle 不會再派發生命週期事件。
         * 此狀態在 Activity.onDestroy() 之前
         */
        DESTROYED,

        /**
         * 在 Activity 已經例項化但未 onCreate() 之前
         */
        INITIALIZED,

        /**
         * 在 Activity 的 onCreate() 之後到 onStop() 之前
         */
        CREATED,

        /**
         * 在 Activity 的 onStart() 之後到 onPause() 之前
         */
        STARTED,

        /**
         * 在 Activity 的 onResume() 之後
         */
        RESUMED;

        public boolean isAtLeast(@NonNull State state) {
            return compareTo(state) >= 0;
        }
    }

State 可能相對比較難以理解,特別是其中列舉值的順序。這裡先不詳細解讀,但是務必記住這幾個列舉值的順序,DESTROYED —— INITIALIZED —— CREATED —— STARTED ——RESUMED,這個對於後面原始碼的理解特別重要。

簡單梳理一下三劍客的關係。生命週期元件 LifecycleOwner 在進入特定的生命週期後,傳送特定的生命週期事件 Event ,通知 Lifcycle 進入特定的 State ,進而回調生命週期觀察者 LifeCycleObserver 的指定方法。

從 addObserver() 下手

面對原始碼無從下手的話,我們就從 Lifecycle 的基本使用入手。

lifecycle.addObserver(LocationUtil( ))

lifecycle 其實就是 getLifecycle()方法,只是在 Kotlin中被 簡寫了。getLifecycle() 是介面 LifecycleOwner 的方法。而 AppCompatActivity 並沒有直接實現 LifecycleOwner,它的父類 FragmentActivity 也沒有,在它的爺爺類 ComponentActivity 中才找到 LifecycleOwner 的蹤影,看一下介面的實現。

@Override
public Lifecycle getLifecycle() {
    return mLifecycleRegistry;
}

mLifecycleRegistryLifecycleRegistry 物件,LifecycleRegistryLifeCycle 的實現類。那麼這裡的 LifecycleRegistry 就是我們的生命週期物件了。來看一下它的 addObserver() 方法。

> LifecycleRegistry.java

......

// 儲存 LifecycleObserver 及其對應的 State
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
        new FastSafeIterableMap<>();

 // 當前生命週期狀態
private State mState;

/**
 * 新增生命週期觀察者 LifecycleObserver
 * 另外要注意生命週期事件的 “倒灌”,如果在 onResume() 中呼叫 addObserver(),
 * 那麼,觀察者依然可以接收到 onCreate 和 onStart 事件。
 * 這麼做的目的是保證 mObserverMap 中的 LifecycleObserver 始終保持在同一狀態
 */
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    // ObserverWithState 是一個靜態內部類
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

    if (previous != null) {
        return;
    }
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    if (lifecycleOwner == null) {
        // it is null we should be destroyed. Fallback quickly
        return;
    }

    // 判斷是否重入
    boolean isReentrance = mAddingObserverCounter != 0 || mHandlinengEvent;
    State targetState = calculateTargetState(observer);
    mAddingObserverCounter++;

    // 如果觀察者的初始狀態小於 targetState ,則同步到 targetState
    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--;
}

這裡面要注意兩個問題。第一個問題是生命週期的 "倒灌問題" ,這是我從 LiveData 那裡借來的一次詞。具體是什麼問題呢?來舉一個例子,即使你在 onResume( ) 中呼叫 addObserver( ) 方法來新增觀察者,觀察者依然可以依次接收到 onCreateonStart 事件 ,最終同步到 targetState 。這個 targetState 是通過 calculateTargetState(observer) 方法計算出來的。

/**
 * 計算出的 targetState 一定是小於等於當前 mState 的
 */
  private State calculateTargetState(LifecycleObserver observer) {
    // 獲取當前 Observer 的前一個 Observer
      Entry<LifecycleObserver, ObserverWithState> previous = mObserverMap.ceil(observer);

      State siblingState = previous != null ? previous.getValue().mState : null;
  // 無重入情況下可不考慮 parentState ,為 null
      State parentState = !mParentStates.isEmpty() ? mParentStates.get(mParentStates.size() - 1)
              : null;
      return min(min(mState, siblingState), parentState);
  }

我們可以新增多個生命週期觀察者,這時候就得注意維護它們的狀態。每次新增新的觀察者的初始狀態是 INITIALIZED ,需要把它同步到當前生命週期狀態,確切的說,同步到一個不大於當前狀態的 targetState 。從原始碼中的計算方式也有所體現,targetState 是 當前狀態 mState,mObserverMap 中最後一個觀察者的狀態 ,有重入情況下 parentState 的狀態 這三者中的最小值。

為什麼要取這個最小值呢?我是這麼理解的,當有新的生命週期事件時,需要將 mObserverMap 中的所有觀察者都同步到新的同一狀態,這個同步過程可能尚未完成,所以新加入的觀察者只能先同步到最小狀態。注意在 addObserver 方法的 while 迴圈中,新的觀察者每改變一次生命週期,都會呼叫 calculateTargetState() 重新計算 targetState

最終的穩定狀態下,沒有生命週期切換,沒有新增新的觀察者,mObserverMap 中的所有觀察者應該處於同一個生命週期狀態。

誰來分發生命週期事件?

觀察者已經新增完成了,那麼如何將生命週期的變化通知觀察者呢?

再回到 ComponentActivity ,你會發現裡面並沒有重寫所有的生命週期函式。唯一讓人可疑的就只有 onCreate() 當中的一行程式碼。

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mSavedStateRegistryController.performRestore(savedInstanceState);
    ReportFragment.injectIfNeededIn(this);
    if (mContentLayoutId != 0) {
        setContentView(mContentLayoutId);
    }
}

這裡的 ReportFragment 就是問題的答案。追進 injectIfNeededIn() 方法。

public static void injectIfNeededIn(Activity activity) {
    // 使用 android.app.FragmentManager 保持相容
    android.app.FragmentManager manager = activity.getFragmentManager();
    if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
        manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
        // Hopefully, we are the first to make a transaction.
        manager.executePendingTransactions();
    }
}

這裡向 Activity 注入了一個沒有頁面的 Fragment 。這就讓我想到了一些動態許可權庫也是這個套路,通過注入 Fragment 來代理許可權請求。不出意外,ReportFragment 才是真正分發生命週期的地方。

@Override
 public void onActivityCreated(Bundle savedInstanceState) {
     super.onActivityCreated(savedInstanceState);
     dispatchCreate(mProcessListener);
     dispatch(Lifecycle.Event.ON_CREATE);
 }

 @Override
 public void onStart() {
     super.onStart();
     dispatchStart(mProcessListener);
     dispatch(Lifecycle.Event.ON_START);
 }

 @Override
 public void onResume() {
     super.onResume();
     dispatchResume(mProcessListener);
     dispatch(Lifecycle.Event.ON_RESUME);
 }

 @Override
 public void onPause() {
     super.onPause();
     dispatch(Lifecycle.Event.ON_PAUSE);
 }

 @Override
 public void onStop() {
     super.onStop();
     dispatch(Lifecycle.Event.ON_STOP);
 }

 @Override
 public void onDestroy() {
     super.onDestroy();
     dispatch(Lifecycle.Event.ON_DESTROY);
     // just want to be sure that we won't leak reference to an activity
     mProcessListener = null;
 }

mProcessListener 是處理應用程序生命週期的,暫時不去管它。

先看一下 dispatch() 方法。

private void dispatch(Lifecycle.Event event) {
    Activity activity = getActivity();
    if (activity instanceof LifecycleRegistryOwner) {
        ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
        return;
    }

    if (activity instanceof LifecycleOwner) {
        Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
        if (lifecycle instanceof LifecycleRegistry) {
            // 呼叫 LifecycleRegistry.handleLifecycleEvent() 方法
            ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
        }
    }
}

ReportFragment 的各個生命週期函式中通過 dispatch() 方法來分發生命週期事件, 然後呼叫 LifecycleRegistryhandleLifecycleEvent() 方法來處理 。為了方便後面的程式碼理解,這裡假定 現在要經歷從 onStart() 同步到 onResume() 的過程,即handleLifecycleEvent() 方法中的引數是 ON_RESUME

// 設定當前狀態並通知觀察者
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
    State next = getStateAfter(event);
    moveToState(next);
}

getStateAfter() 的作用是根據 Event 獲取事件之後處於的狀態 ,並通知觀察者同步到此生命週期狀態。

static State getStateAfter(Event event) {
    switch (event) {
        case ON_CREATE:
        case ON_STOP:
            return CREATED;
        case ON_START:
        case ON_PAUSE:
            return STARTED;
        case ON_RESUME:
            return RESUMED;
        case ON_DESTROY:
            return DESTROYED;
        case ON_ANY:
            break;
    }
    throw new IllegalArgumentException("Unexpected event value " + event);
}

引數是 ON_RESUME ,所以需要同步到的狀態是 RESUMED 。接下來看看 moveToState() 方法的邏輯。

private void moveToState(State next) {
    if (mState == next) {
        return;
    }
    mState = next;
    if (mHandlingEvent || mAddingObserverCounter != 0) {
        mNewEventOccurred = true;
        // we will figure out what to do on upper level.
        return;
    }
    mHandlingEvent = true;
    sync();
    mHandlingEvent = false;
}

首先將要同步到的生命週期狀態賦給當前生命週期狀態 mState ,此時 mState 的值就是 RESUMED 。然後呼叫 sync() 方法同步所有觀察者的狀態。

private void sync() {
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    if (lifecycleOwner == null) {
        Log.w(LOG_TAG, "LifecycleOwner is garbage collected, you shouldn't try dispatch "
                + "new events from it.");
        return;
    }
    while (!isSynced()) {
        mNewEventOccurred = false;
        // mState 是當前狀態,如果 mState 小於 mObserverMap 中的狀態值,呼叫 backwardPass()
        if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
            backwardPass(lifecycleOwner);
        }
        Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
        // 如果 mState 大於 mObserverMap 中的狀態值,呼叫 forwardPass()
        if (!mNewEventOccurred && newest != null
                && mState.compareTo(newest.getValue().mState) > 0) {
            forwardPass(lifecycleOwner);
        }
    }
    mNewEventOccurred = false;
}

這裡會比較 mStatemObserverMap 中觀察者的 State 值,判斷是需要向前還是向後同步狀態。現在 mState 的值是 RESUMED , 而觀察者還停留在上一狀態 STARTED ,所以觀察者的狀態都得往前挪一步,這裡呼叫的是 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();
        // 向上傳遞事件,直到 observer 的狀態值等於當前狀態值
        while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
                && mObserverMap.contains(entry.getKey()))) {
            pushParentState(observer.mState);
            // 分發生命週期事件
            observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
            popParentState();
        }
    }
}

forwardPass() 會同步 mObserverMap 中的所有觀察者到指定生命週期狀態,如果跨度比較大,會依次分發中間狀態。分發生命週期事件最終依賴 ObserverWithStatedispatchEvent() 方法。

這裡先暫停存檔一下,不繼續往下追原始碼。上面假定的場景是 ON_STARTON_RESUME 的過程。現在假定另一個場景,我直接按下 Home 鍵返回桌面,當前 Activity 的生命週期從onResumedonPaused ,流程如下。

  1. ReportFragment 呼叫 dispatch(Lifecycle.Event.ON_PAUSE) ,分發 ON_PAUSE

  2. 呼叫 LifecycleRegistry.handleLifecycleEvent() 方法,引數是 ON_PAUSE

  3. getStateAfter() 得到要同步到的狀態是 STARTED ,並賦給 mState,接著呼叫 moveToState()

  4. moveToState(Lifecycle.State.STARTED) 中呼叫 sync() 方法同步

  5. sync() 方法中,mState 的值是 STARTED ,而 mObserverMap 中觀察者的狀態都是 RESUMED 。所以觀察者們都需要往後挪一步,這呼叫的就是 backwardPass() 方法。

backwardPass() 方法其實和 forwardPass() 差不多。

private void backwardPass(LifecycleOwner lifecycleOwner) {
    Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
            mObserverMap.descendingIterator();
    while (descendingIterator.hasNext() && !mNewEventOccurred) {
        Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();
        ObserverWithState observer = entry.getValue();
        // 向下傳遞事件,直到 observer 的狀態值等於當前狀態值
        while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
                && mObserverMap.contains(entry.getKey()))) {
            Event event = downEvent(observer.mState);
            pushParentState(getStateAfter(event));
            // 分發生命週期事件
            observer.dispatchEvent(lifecycleOwner, event);
            popParentState();
        }
    }
}

二者唯一的區別就是獲取要分發的事件,一個是 upEvent() ,一個是 downEvent()

upEvent() 是獲取 state 升級所需要經歷的事件,downEvent() 是獲取 state 降級所需要經歷的事件。

private static Event upEvent(State state) {
    switch (state) {
        case INITIALIZED:
        case DESTROYED:
            return ON_CREATE;
        case CREATED:
            return ON_START;
        case STARTED:
            return ON_RESUME;
        case RESUMED:
            throw new IllegalArgumentException();
    }
    throw new IllegalArgumentException("Unexpected state value " + state);
}

private static Event downEvent(State state) {
    switch (state) {
        case INITIALIZED:
            throw new IllegalArgumentException();
        case CREATED:
            return ON_DESTROY;
        case STARTED:
            return ON_STOP;
        case RESUMED:
            return ON_PAUSE;
        case DESTROYED:
            throw new IllegalArgumentException();
    }
    throw new IllegalArgumentException("Unexpected state value " + state);
}

STARTEDRESUMED 需要升級,upEvent(STARTED) 的返回值是 ON_RESUME
RESUMEDSTARTED 需要降級,downEvent(RESUMED)的返回值是 ON_PAUSE

看到這不知道你有沒有一點懵,State 和 Event 的關係我也摸索了很長一段時間才理清楚。首先還記得 State 的列舉值順序嗎?

DESTROYED —— INITIALIZED —— CREATED —— STARTED —— RESUMED

DESTROYED 最小,RESUMED 最大 。onResume 進入到 onPause 階段最後分發的生命週期事件的確是 ON_PAUSE ,但是將觀察者的狀態置為了 STARTED 。這是為什麼呢?

關於 StateEvent 的關係,官網給出了一張圖,如下所所示:

但我不得不說,畫的的確有點抽象,其實應該換個畫法。再來一張我在 這裡 看到的一張圖:

狀態之間的事件,事件之後的狀態,狀態之間的大小 ,是不是有種一目瞭然的感覺?理解這幅圖很重要,可以說搞不清 Event 和 State 的關係,就看不懂 Lifecycle 的原始碼。

誰來回調你的註解方法 ?

再讀取剛才的暫停存檔,同步 Observer 生命週期的 sync() 方法最終會呼叫 ObserverWithStatedispatchEvent() 方法。

static class ObserverWithState {
    State mState;
    GenericLifecycleObserver mLifecycleObserver;

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

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

mLifecycleObserver 通過 Lifecycling.getCallback() 方法賦值。

@NonNull
static GenericLifecycleObserver getCallback(Object object) {
    if (object instanceof FullLifecycleObserver) {
        return new FullLifecycleObserverAdapter((FullLifecycleObserver) object);
    }

    if (object instanceof GenericLifecycleObserver) {
        return (GenericLifecycleObserver) object;
    }

    final Class<?> klass = object.getClass();
    int type = getObserverConstructorType(klass);
    // 獲取 type
    // GENERATED_CALLBACK 表示註解生成的程式碼
    // REFLECTIVE_CALLBACK 表示使用反射
    if (type == GENERATED_CALLBACK) {
        List<Constructor<? extends GeneratedAdapter>> constructors =
                sClassToAdapters.get(klass);
        if (constructors.size() == 1) {
            GeneratedAdapter generatedAdapter = createGeneratedAdapter(
                    constructors.get(0), object);
            return new SingleGeneratedAdapterObserver(generatedAdapter);
        }
        GeneratedAdapter[] adapters = new GeneratedAdapter[constructors.size()];
        for (int i = 0; i < constructors.size(); i++) {
            adapters[i] = createGeneratedAdapter(constructors.get(i), object);
        }
        return new CompositeGeneratedAdaptersObserver(adapters);
    }
    return new ReflectiveGenericLifecycleObserver(object);
}

如果使用的是 DefaultLifecycleObserver ,而 DefaultLifecycleObserver 又是繼承 FullLifecycleObserver 的,所以這裡會返回 FullLifecycleObserverAdapter

如果只是普通的 LifecycleObserver ,那麼就需要通過 getObserverConstructorType() 方法判斷使用的是註解還是反射。

private static int getObserverConstructorType(Class<?> klass) {
    if (sCallbackCache.containsKey(klass)) {
        return sCallbackCache.get(klass);
    }
    int type = resolveObserverCallbackType(klass);
    sCallbackCache.put(klass, type);
    return type;
}

private static int resolveObserverCallbackType(Class<?> klass) {
    // anonymous class bug:35073837
    // 匿名內部類使用反射
    if (klass.getCanonicalName() == null) {
        return REFLECTIVE_CALLBACK;
    }

    // 尋找註解生成的 GeneratedAdapter 類
    Constructor<? extends GeneratedAdapter> constructor = generatedConstructor(klass);
    if (constructor != null) {
        sClassToAdapters.put(klass, Collections
                .<Constructor<? extends GeneratedAdapter>>singletonList(constructor));
        return GENERATED_CALLBACK;
    }

    // 尋找被 OnLifecycleEvent 註解的方法
    boolean hasLifecycleMethods = ClassesInfoCache.sInstance.hasLifecycleMethods(klass);
    if (hasLifecycleMethods) {
        return REFLECTIVE_CALLBACK;
    }

    // 沒有找到註解生成的 GeneratedAdapter 類,也沒有找到 OnLifecycleEvent 註解,
    // 則向上尋找父類
    Class<?> superclass = klass.getSuperclass();
    List<Constructor<? extends GeneratedAdapter>> adapterConstructors = null;
    if (isLifecycleParent(superclass)) {
        if (getObserverConstructorType(superclass) == REFLECTIVE_CALLBACK) {
            return REFLECTIVE_CALLBACK;
        }
        adapterConstructors = new ArrayList<>(sClassToAdapters.get(superclass));
    }

    // 尋找是否有介面實現
    for (Class<?> intrface : klass.getInterfaces()) {
        if (!isLifecycleParent(intrface)) {
            continue;
        }
        if (getObserverConstructorType(intrface) == REFLECTIVE_CALLBACK) {
            return REFLECTIVE_CALLBACK;
        }
        if (adapterConstructors == null) {
            adapterConstructors = new ArrayList<>();
        }
        adapterConstructors.addAll(sClassToAdapters.get(intrface));
    }
    if (adapterConstructors != null) {
        sClassToAdapters.put(klass, adapterConstructors);
        return GENERATED_CALLBACK;
    }

    return REFLECTIVE_CALLBACK;
}

注意其中的 hasLifecycleMethods() 方法。

boolean hasLifecycleMethods(Class klass) {
    if (mHasLifecycleMethods.containsKey(klass)) {
        return mHasLifecycleMethods.get(klass);
    }

    Method[] methods = getDeclaredMethods(klass);
    for (Method method : methods) {
        OnLifecycleEvent annotation = method.getAnnotation(OnLifecycleEvent.class);
        if (annotation != null) {
            createInfo(klass, methods);
            return true;
        }
    }
    mHasLifecycleMethods.put(klass, false);
    return false;
}

這裡會去尋找 OnLifecycleEvent 註解。所以我們通過 OnLifecycleEvent 註解實現的 MyObserver 的型別是 REFLECTIVE_CALLBACK ,表示使用反射呼叫。注意另一個型別 GENERATED_CALLBACK 表示使用註解生成的程式碼,而不是反射。

所以,所以,Lifecycle 可以選擇使用 apt 編譯期生成程式碼來避免使用執行時反射,以優化效能?好像還真是這麼一回事。這就讓我想到了 EventBus 的索引加速 預設也是關閉的。看吧,這就是閱讀原始碼的好處,總能發現自己的知識盲區。新增下列依賴,來提速 LifeCycle 吧 !

kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"

為了方便解析,還是回到反射呼叫上來。

我們自己定義的在普通的觀察者呼叫的是 ReflectiveGenericLifecycleObserver.onStateChanged()

class ReflectiveGenericLifecycleObserver implements GenericLifecycleObserver {
    private final Object mWrapped; // Observer 物件
    private final CallbackInfo mInfo; // 反射獲取註解資訊

    ReflectiveGenericLifecycleObserver(Object wrapped) {
        mWrapped = wrapped;
        mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());
    }

    @Override
    public void onStateChanged(LifecycleOwner source, Event event) {
        // 呼叫 ClassesInfoCache.CallbackInfo.invokeCallbacks()
        mInfo.invokeCallbacks(source, event, mWrapped);
    }
}

再追進 ClassesInfoCache.CallbackInfo.invokeCallbacks() 方法。

void invokeCallbacks(LifecycleOwner source, Lifecycle.Event event, Object target) {
    // 不僅分發了當前生命週期事件,還分發了 ON_ANY
    invokeMethodsForEvent(mEventToHandlers.get(event), source, event, target);
    invokeMethodsForEvent(mEventToHandlers.get(Lifecycle.Event.ON_ANY), source, event,
            target);
}

private static void invokeMethodsForEvent(List<MethodReference> handlers,
        LifecycleOwner source, Lifecycle.Event event, Object mWrapped) {
    if (handlers != null) {
        for (int i = handlers.size() - 1; i >= 0; i--) {
            handlers.get(i).invokeCallback(source, event, mWrapped);
        }
    }
}

void invokeCallback(LifecycleOwner source, Lifecycle.Event event, Object target) {
    //noinspection TryWithIdenticalCatches
    try {
        switch (mCallType) {
            case CALL_TYPE_NO_ARG:
                mMethod.invoke(target);
                break;
            case CALL_TYPE_PROVIDER:
                mMethod.invoke(target, source);
                break;
            case CALL_TYPE_PROVIDER_WITH_EVENT:
                mMethod.invoke(target, source, event);
                break;
        }
    } catch (InvocationTargetException e) {
        throw new RuntimeException("Failed to call observer method", e.getCause());
    } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
    }
}

其實就很簡單了,反射呼叫 OnLifecycleEvent 註解標記的生命週期回撥方法。

Wait For More

本想再接著分析程序生命週期 ProcessLifecycleOwnerLifecycle 的協程使用相關原始碼,可是文章篇幅有點過長了,就留到下一篇吧,敬請期待!

參考和推薦

下面幾篇文章同樣優秀,直接仔細研讀,推薦給大家。

  • Android架構之美-Lifecycle
  • Jetpack和LifeCycle(三)
  • Android-Lifecycle超能解析-生命週期的那些事兒

文章首發微信公眾號: 秉心說 , 專注 Java 、 Android 原創知識分享,LeetCode 題解。

更多最新原創文章,掃碼關注我吧!

相關推薦

講解 Jetpack LifeCycle 原始碼

前一篇 硬核講解 Jetpack 之 LifeCycle 使用篇 主要介紹了 LifeCycle 存在的意義,基本和進階的使用方法。今天話不多說,直接開始擼原始碼。 本文基於我手裡的 android_9.0.0_r45 原始碼,所有相關原始碼包括註釋都上傳到了我的 Github ,可以直接 clone 下來對

Android JetpackLifecycle原始碼分析

Lifecycle元件中的類結構,LifecycleOwner表示擁有生命週期功能。 Lifecycle定義了Android中的生命週期的介面。而LifecycleObserver是生命週期的監聽的介面。Lifecycle可以註冊和反註冊LifecycleO

Android Jetpack Lifecycle

前言 在日常的開發中,我們通常需要在 Activity / Fragment 的生命週期方法中進行一些繁重的操作,這樣使程式碼看起來十分臃腫。Lifecycle 的引入主要是用來管理和響應 Activity / Fragment 的生命週期的變化,幫助我們編寫出更易於組織且通常更加輕

【自制作業系統01】講解計算機的啟動過程

本講只為講明白下面一個問題: 我們按下開機鍵後究竟發生了什麼? 好的,這似乎是好多人都特別想搞明白的一個問題,有時候非常納悶,為什麼一個看似這麼簡單的問題,就是搜不到一個直面問題的答案呢? 好問題,我也不知道為什麼會這樣,但我猜是因為: 其一,似懂非懂的人太多,他們其實也不知道究竟發生了什麼,所以只能模

全網最講解計算機啟動流程

本講只為講明白下面一個問題: > 我們按下開機鍵後究竟發生了什麼? 好的,這似乎是好多人都特別想搞明白的一個問題,有時候非常納悶,為什麼一個看似這麼簡單的問題,就是搜不到一個直面問題的答案呢? 好問題,我也不知道為什麼會這樣,但我猜是因為: - **其一**,似懂非懂的人太多,他們其實也不知道究竟發生

Android Jetpack架構元件 Lifecycle原始碼

一、前言 最近簡單看了下google推出的框架Jetpack,感覺此框架的內容可以對平時的開發有很大的幫助,也可以解決很多開發中的問題,對程式碼的邏輯和UI介面實現深層解耦,打造資料驅動型UI介面。 Android Architecture元件是Android Jetpa

Android Jetpack架構元件 Paging(使用、原始碼

1、前言 最近簡單看了下google推出的框架Jetpack,感覺此框架的內容可以對平時的開發有很大的幫助,也可以解決很多開發中的問題,對程式碼的資料邏輯和UI介面深層解耦,實現資料驅動型的ui。 Android Architecture元件是Android Jetpac

OkHttp原始碼詳解二完結

1. 請大家思考幾個問題 在開始本文之前,請大家思考如下幾個問題。並請大家帶著這幾個問題,去本文尋找答案。如果你對下面幾個問題的答案瞭如指掌那本文可以略過不看 在瀏覽器中輸入一個網址,按回車後發生了什麼? Okhttp的TCP連線建立發生在什麼時候? Okht

【安卓本卓】Android系統原始碼(二)Source Insight

Source Insight(以下簡稱SI) 一、SI簡介        SI是一款面向專案開發的程式編輯器和程式碼瀏覽器,它提供了一個檢視將分散在各個地方的程式碼匯合在一起形成一個虛擬的整體,供開發者方便地閱讀和編輯,如下圖所示。它已經持續維護了10多年了,旨在提

文章徹底讀懂HashMapHashMap原始碼解析(下)

put函式原始碼解析 //put函式入口,兩個引數:key和value public V put(K key, V value) { /*下面分析這個函式,注意前3個引數,後面 2個引數這裡不太重要,因為所有的put 操作後面的2個引數預設值都一樣 */

文章徹底讀懂HashMapHashMap原始碼解析(上)

就身邊同學的經歷來看,HashMap是求職面試中名副其實的“明星”,基本上每一加公司的面試多多少少都有問到HashMap的底層實現原理、原始碼等相關問題。 在秋招面試準備過程中,博主閱讀過很多關於HashMap原始碼分析的文章,漫長的拼湊式閱讀之後,博主沒有看到過

spring-boot-2.0.3不一樣系列原始碼 - 階段總結

前言   開心一刻     朋友喜歡去按摩,第一次推門進來的是一個學生美眉,感覺還不錯;後來經常去,有時是護士,有時是空姐,有時候是教師。昨天晚上推門進去的是一個女警察,長得賊好看,身材也很好,朋友嗷的一聲就撲上去了。然後他就被抓起來了,罪名是:嫖娼、襲警、強姦未遂。   路漫漫其修遠兮,吾將上下而求索

Dubbo原始碼解析consumer呼叫

閱讀須知 dubbo版本:2.6.0 spring版本:4.3.8 文章中使用/* */註釋的方法會做深入分析 正文 在分析consumer初始化時,我們看到了關聯服務引用建立代理的過程,最終會呼叫JavassistProxyFactory的getP

IP、固 簡記

IP核(Intellectual Property core),即智慧財產權核。 IP核是一段具有特定電路功能的硬體描述語言程式,該程式通常與積體電路工藝無關,可以移植到不同的半導體工藝中去生產積體電

深入淺出Mybatis原始碼系列(三)---配置詳解properties與environments(mybatis原始碼

上篇文章《深入淺出Mybatis原始碼系列(二)---配置簡介(mybatis原始碼篇)》我們通過對mybatis原始碼的簡單分析,可看出,在mybatis配置檔案中,在configuration根節點下面,可配置properties、typeAliases、plugins、

Dubbo原始碼解析provider呼叫

閱讀須知 dubbo版本:2.6.0 spring版本:4.3.8 文章中使用/* */註釋的方法會做深入分析 正文 在之前的原始碼分析文章中,我們看到了dubbo用netty作為底層的網路通訊框架,熟悉netty的同學應該知道,使用netty時我們會使用它

原始碼分析String原始碼分析二

    前面已經分析過String原始碼為什麼是不可變的,同時通過我們常用的String的相關的類StringBuffer和StringBuilder,我們可以發現String類中欄位名被定義為了final型別,這樣的話將只能被賦值一次。接下來,繼續看String原始碼實現的

原始碼分析String原始碼分析三

    上期已經討論了比較器的相關的問題。同時也提出問題明明父類已經實現了某個介面,子類為什麼還是要實現同樣的介面呢。這究竟有什麼意義呢。通過使用度孃的多次探究之後最終我還是沒有發現說它有什麼特別的含義。我認為的最大的含義就是告訴使用者這個類實現了這樣的一個介面。方便使用者進

【安卓本卓】Android系統原始碼(一)原始碼獲取、原始碼目錄結構及原始碼閱讀工具簡介

前言 古人常說,“熟讀唐詩三百首,不會作詩也會吟”,說明了大量閱讀詩歌名篇對學習作詩有非常大的幫助。做開發也一樣,Android原始碼是全世界最優秀的Android工程師編寫的程式碼,也是Android開發中絕對的權威所在。Android系統開源,且佔據了當今手機系統世界的絕大部分江山,各大手機廠商要做手機系

Spring Cloud Netflix Zuul原始碼分析路由註冊

微信公眾號:I am CR7如有問題或建議,請在下方留言;最近更新:2018-12-29 前言 繼上一篇Spring Cloud Netflix Zuul原始碼分析之預熱篇,我們知道了兩個重要的類:ZuulHandlerMapping和SimpleControllerHandlerA