主頁 > 移動端開發 > Jetpack-Lifecycle原始碼決議

Jetpack-Lifecycle原始碼決議

2021-12-14 08:01:53 移動端開發

Lifecycle原始碼決議

原始碼版本:

  • Lifecycle:2.4.0
  • androidx.activity:activity:1.4.0
  • androidx.fragment:fragment:1.4.0

使用

宣告LifecycleObserver

1. DefaultLifecycleObserver

生命周期狀態改變時,會呼叫對應的方法,可根據需要,重寫某個方法,

val lifecycleObserver = object : DefaultLifecycleObserver {

    override fun onResume(owner: LifecycleOwner) {
        super.onResume(owner)
    }

    override fun onPause(owner: LifecycleOwner) {
        super.onPause(owner)
    }
}

2. LifecycleEventObserver

生命周期狀態改變時,會呼叫onStateChanged方法,

val lifecycleObserver = object : LifecycleEventObserver {

    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {

    }
}

3. OnLifecycleEvent(已棄用)

生命周期狀態改變時,會呼叫LifecycleObserver子類被對應event標注的方法,使用OnLifecycleEvent注解標注方法上,方法要求:方法名稱任意,方法引數可無可1個(必須是LifecycleOwner)、可2個(必須先后是LifecycleOwnerLifecycle.Event、且event必須是Lifecycle.Event.ON_ANY),

val lifecycleObserver = object : LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun onCreate() {
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun onResume(owner: LifecycleOwner) {
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    fun onAny(owner: LifecycleOwner, event: Lifecycle.Event) {
    }
}

添加觀察者

lifecycle.addObserver(lifecycleObserver)

移除觀察者

lifecycle.removeObserver(lifecycleObserver)

獲取當前狀態

val state = lifecycle.currentState

原始碼

宣告LifecycleObserver

1. DefaultLifecycleObserver

DefaultLifecycleObserver介面

public interface DefaultLifecycleObserver extends FullLifecycleObserver {
    @Override
    default void onCreate(@NonNull LifecycleOwner owner) {}

    @Override
    default void onStart(@NonNull LifecycleOwner owner) {}

    @Override
    default void onResume(@NonNull LifecycleOwner owner) {}

    @Override
    default void onPause(@NonNull LifecycleOwner owner) {}

    @Override
    default void onStop(@NonNull LifecycleOwner owner) {}

    @Override
    default void onDestroy(@NonNull LifecycleOwner owner) {}
}

DefaultLifecycleObserver介面對FullLifecycleObserver介面進行了默認實作,所以可以按需實作某個方法,由于此介面方法使用default,這一特性是從 Java 8才開始有的,所以需要配置以 Java 8及以上作為編譯版本才可以使用,

FullLifecycleObserver介面

interface FullLifecycleObserver extends LifecycleObserver {

    void onCreate(LifecycleOwner owner);

    void onStart(LifecycleOwner owner);

    void onResume(LifecycleOwner owner);

    void onPause(LifecycleOwner owner);

    void onStop(LifecycleOwner owner);

    void onDestroy(LifecycleOwner owner);
}

生命周期狀態改變時,會呼叫對應的方法(呼叫邏輯后面講),FullLifecycleObserver介面不是public的,所以不能使用,推薦使用DefaultLifecycleObserver

LifecycleObserver介面

public interface LifecycleObserver {

}

LifecycleObserver是一個空介面,用于標記可以被Lifecycle添加、洗掉,可以使用它的子介面DefaultLifecycleObserverLifecycleEventObserverOnLifecycleEvent(已棄用)標注方法的子類,來通知生命周期事件,

2. LifecycleEventObserver

LifecycleEventObserver介面

public interface LifecycleEventObserver extends LifecycleObserver {

    void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}

生命周期狀態改變時,會呼叫onStateChanged方法(呼叫邏輯后面講),引數event為當前的事件(ON_CREATEON_STARTON_RESUMEON_PAUSEON_STOPON_DESTROY),

3. OnLifecycleEvent(已棄用)

OnLifecycleEvent注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Deprecated
public @interface OnLifecycleEvent {
    Lifecycle.Event value();
}

生命周期狀態改變時,會呼叫LifecycleObserver子類被對應event標注的方法(呼叫邏輯后面講),OnLifecycleEvent已被@Deprecated標注,已經被棄用,后面會減少對此的講解,

添加觀察者

使用

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // 添加
        lifecycle.addObserver(lifecycleObserver)
    }
}

獲取到Lifecycle,然后進行添加,我們先看一下Lifecycle類,

Lifecycle

Lifecycle類

public abstract class Lifecycle {

    // 協程相關,存放coroutineScope的,
    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    @NonNull
    AtomicReference<Object> mInternalScopeRef = new AtomicReference<>();

    // 添加觀察者
    @MainThread
    public abstract void addObserver(@NonNull LifecycleObserver observer);

    // 移除觀察者
    @MainThread
    public abstract void removeObserver(@NonNull LifecycleObserver observer);

    // 獲取當前的狀態
    @MainThread
    @NonNull
    public abstract State getCurrentState();

    // 事件類
    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;

        // 比較這個狀態是否大于等于給定的狀態,RESUMED > STARTED > CREATED > INITIALIZED > DESTROYED,
        public boolean isAtLeast(@NonNull State state) {
            return compareTo(state) >= 0;
        }
    }
}

StateEvent的關系圖

LifecycleOwner

我們再來看一下,從ActvityFragment中是如何獲取到Lifecycle的,因為androidx.activity.ComponentActivityandroidx.fragment.app.Fragment都實作了LifecycleOwner介面,表明可以提供Lifecycle實體,相關的原始碼如下:

LifecycleOwner介面

public interface LifecycleOwner {

    @NonNull
    Lifecycle getLifecycle();
}

Activity

androidx.activity.ComponentActivity --> getLifecycle方法

public class ComponentActivity extends androidx.core.app.ComponentActivity implements
        ContextAware,
        LifecycleOwner,
        ViewModelStoreOwner,
        HasDefaultViewModelProviderFactory,
        SavedStateRegistryOwner,
        OnBackPressedDispatcherOwner,
        ActivityResultRegistryOwner,
        ActivityResultCaller,
        MenuHost {

    private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

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

androidx.core.app.ComponentActivity --> getLifecycle方法

public class ComponentActivity extends Activity implements
        LifecycleOwner,
        KeyEventDispatcher.Component {

    private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

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

說明:

  1. MyActivity繼承關系:MyActivity->AppCompatActivity->FragmentActivity->androidx.activity.ComponentActivity->androidx.core.app.ComponentActivity
  2. 雖然androidx.activity.ComponentActivity和父類androidx.core.app.ComponentActivity都實作了LifecycleOwner介面,但是androidx.core.app.ComponentActivity的被子類androidx.activity.ComponentActivity覆寫,導致父類的無效,

Fragment

androidx.fragment.app.Fragment --> getLifecycle方法

public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner,
        ViewModelStoreOwner, HasDefaultViewModelProviderFactory, SavedStateRegistryOwner,
        ActivityResultCaller {
    LifecycleRegistry mLifecycleRegistry;

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

    public Fragment() {
        initLifecycle();
    }

    private void initLifecycle() {
        mLifecycleRegistry = new LifecycleRegistry(this);
    }
}

androidxActivityFragment都實作了LifecycleOwner介面,并回傳的都是LifecycleRegistry類,我們接下來看一下LifecycleRegistry類,

LifecycleRegistry

構造方法

LifecycleRegistry --> 構造方法

public LifecycleRegistry(@NonNull LifecycleOwner provider) {
    // 默認,強制在主執行緒執行,mEnforceMainThread為true
    this(provider, true);
}

private LifecycleRegistry(@NonNull LifecycleOwner provider, boolean enforceMainThread) {
    // 記錄LifecycleOwner
    mLifecycleOwner = new WeakReference<>(provider);
    // 當前狀態為INITIALIZED
    mState = INITIALIZED;
    mEnforceMainThread = enforceMainThread;
}

我們接下來再看一下addObserver方法,

addObserver

LifecycleRegistry --> addObserver方法

@Override
public void addObserver(@NonNull LifecycleObserver observer) {
    // 當mEnforceMainThread為true時,必須是在主執行緒呼叫,否則拋出例外
    enforceMainThreadIfNeeded("addObserver");  
    // 觀察者的初始化狀態
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    // 生成ObserverWithState,它包含狀態和觀察者,它會把上面全部3種情況的LifecycleObserver統一轉換成LifecycleEventObserver,
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    // 將觀察者添加到map,如果已經添加,則直接回傳,
    // putIfAbsent,如果傳入key對應的value已經存在,就回傳存在的value,不進行替換,如果不存在,就添加key和value,并回傳null,
    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);    
    if (previous != null) {
        return;
    }
    // 獲取LifecycleOwner實體,一般來說是Activity或者Fragment實體,
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    if (lifecycleOwner == null) {
        // 物件為空,說明已經被銷毀,直接回傳,
        return;
    }

    // isReentrance:是否是再次進入
    // 1.mAddingObserverCounter:添加中的觀察者數量,在執行前加1,在執行后減1,又因為addObserver方法強制在主執行緒執行(沒有并發),所以它一般都為0,之所以不為0,是因為它在添加的observer的生命周期回呼的方法內,又呼叫addObserver方法增加了一個新的LifecycleObserver,
    // 2.mHandlingEvent:是否正在處理事件中,
    boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
    // 計算目標狀態
    State targetState = calculateTargetState(observer);
    mAddingObserverCounter++;
    // statefulObserver.mState.compareTo(targetState) < 0:說明觀察者ObserverWithState的狀態未到達目標狀態,
    // mObserverMap.contains(observer):上面已添加,這邊再判斷是否包含,是因為它在添加的observer的生命周期回呼的方法內,呼叫了removeObserver,
    // 使用while,保證依次分發所有的事件,
    while ((statefulObserver.mState.compareTo(targetState) < 0
            && mObserverMap.contains(observer))) {            
        pushParentState(statefulObserver.mState);
        // 獲取觀察者狀態的下一個事件
        final Event event = Event.upFrom(statefulObserver.mState);
        if (event == null) {
            throw new IllegalStateException("no event up from " + statefulObserver.mState);
        }
        // 觀察者ObserverWithState分發事件,通知被Lifecycle添加的LifecycleObserver狀態改變,講ObserverWithState時會介紹,
        statefulObserver.dispatchEvent(lifecycleOwner, event);        
        popParentState();
        // mState可能被更改,重新計算,
        targetState = calculateTargetState(observer);
    }

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

說明:

  1. 目標狀態一般為mState(當前狀態),觀察者ObserverWithState初始化狀態一般為INITIALIZED,如果觀察者的狀態一直未到達目標狀態,則一直回圈分發事件,直到相同為止,

例如:如果在ActivityonResumeaddObserver,則當前狀態為RESUMED,觀察者的狀態為INITIALIZEDRESUMED,所以此觀察者會依次接收到ON_CREATEON_STARTON_RESUME事件或對應的回呼,

我們再來看一下帶狀態的觀察者ObserverWithState,以及它的dispatchEvent分發方法,

ObserverWithState

ObserverWithState類

static class ObserverWithState {
    State mState;
    LifecycleEventObserver mLifecycleObserver;

    ObserverWithState(LifecycleObserver observer, State initialState) {
        // 把上面全部3種情況的LifecycleObserver統一轉換成LifecycleEventObserver,
        mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
        mState = initialState;
    }

    void dispatchEvent(LifecycleOwner owner, Event event) {
        State newState = event.getTargetState();
        mState = min(mState, newState);
        // 用轉換后的LifecycleEventObserver通知被Lifecycle添加的LifecycleObserver狀態改變,
        mLifecycleObserver.onStateChanged(owner, event);
        mState = newState;
    }
}

ObserverWithState帶狀態的觀察者,它統一了全部3種情況的LifecycleObserver,以及dispatchEvent方法,用轉換后的LifecycleEventObserver通知被Lifecycle添加的LifecycleObserver狀態改變,我們再來看一下Lifecycling它是如何統一的,

Lifecycling

Lifecycling --> lifecycleEventObserver方法

@NonNull
@SuppressWarnings("deprecation")
static LifecycleEventObserver lifecycleEventObserver(Object object) {
    // 是否是LifecycleEventObserver子類
    boolean isLifecycleEventObserver = object instanceof LifecycleEventObserver;
    // 是否是FullLifecycleObserver子類
    boolean isFullLifecycleObserver = object instanceof FullLifecycleObserver;
    if (isLifecycleEventObserver && isFullLifecycleObserver) {
        // 兩者都是,需要適配,兩個樣式回呼都通知,
        return new FullLifecycleObserverAdapter((FullLifecycleObserver) object,
                (LifecycleEventObserver) object);
    }
    if (isFullLifecycleObserver) {
        // 只是FullLifecycleObserver,需要適配,只回呼一個,
        return new FullLifecycleObserverAdapter((FullLifecycleObserver) object, null);
    }

    if (isLifecycleEventObserver) {
        // 只是LifecycleEventObserver,不用適配,直接回傳即可,
        return (LifecycleEventObserver) object;
    }

    // 使用OnLifecycleEvent注解的處理
    final Class<?> klass = object.getClass();
    int type = getObserverConstructorType(klass);
    if (type == GENERATED_CALLBACK) {
	    // 使用OnLifecycleEvent注解,并且依賴了androidx.lifecycle:lifecycle-compiler注解處理器,使用注解處理器優化反射帶來的性能問題,
        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);
    }
    // 使用OnLifecycleEvent注解,并且未依賴注解處理器,使用反射處理,
    return new ReflectiveGenericLifecycleObserver(object);
}

我們再來看一下具體實作,

LifecycleEventObserver Adapter

LifecycleEventObserver Adapter一共有4個,FullLifecycleObserverAdapterSingleGeneratedAdapterObserverCompositeGeneratedAdaptersObserverReflectiveGenericLifecycleObserver,和OnLifecycleEvent注解相關的3個,由于OnLifecycleEvent已經棄用,所以我們只講1個反射的,注解處理器的2個它們的方法要求和反射的相同,只不過它們是在編譯期檢測的,

FullLifecycleObserverAdapter

FullLifecycleObserverAdapter類

class FullLifecycleObserverAdapter implements LifecycleEventObserver {

    private final FullLifecycleObserver mFullLifecycleObserver;
    private final LifecycleEventObserver mLifecycleEventObserver;

    FullLifecycleObserverAdapter(FullLifecycleObserver fullLifecycleObserver,
            LifecycleEventObserver lifecycleEventObserver) {
        mFullLifecycleObserver = fullLifecycleObserver;
        mLifecycleEventObserver = lifecycleEventObserver;
    }

    @Override
    public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
        // 以對應生命周期方法回呼方式通知
        switch (event) {
            case ON_CREATE:
                mFullLifecycleObserver.onCreate(source);
                break;
            case ON_START:
                mFullLifecycleObserver.onStart(source);
                break;
            case ON_RESUME:
                mFullLifecycleObserver.onResume(source);
                break;
            case ON_PAUSE:
                mFullLifecycleObserver.onPause(source);
                break;
            case ON_STOP:
                mFullLifecycleObserver.onStop(source);
                break;
            case ON_DESTROY:
                mFullLifecycleObserver.onDestroy(source);
                break;
            case ON_ANY:
                throw new IllegalArgumentException("ON_ANY must not been send by anybody");
        }
        // 以狀態改變回呼方式通知
        if (mLifecycleEventObserver != null) {
            mLifecycleEventObserver.onStateChanged(source, event);
        }
    }
}

ObserverWithState呼叫dispatchEvent的時候,如果是使用DefaultLifecycleObserverLifecycleEventObserver,則會呼叫此onStateChanged方法,以通知被Lifecycle添加的LifecycleObserver狀態改變,

ReflectiveGenericLifecycleObserver

ReflectiveGenericLifecycleObserver類

@Deprecated
class ReflectiveGenericLifecycleObserver implements LifecycleEventObserver {
    private final Object mWrapped;
    private final androidx.lifecycle.ClassesInfoCache.CallbackInfo mInfo;

    @SuppressWarnings("deprecation")
    ReflectiveGenericLifecycleObserver(Object wrapped) {
        mWrapped = wrapped;
        // 獲取觀察者類的資訊,內部會決議判斷被OnLifecycleEvent注解的方法宣告是否正確,
        mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());
    }

    @Override
    public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Event event) {
        // 呼叫被OnLifecycleEvent標注的對應的方法,通知回呼,
        mInfo.invokeCallbacks(source, event, mWrapped);
    }
}

ObserverWithState呼叫dispatchEvent的時候,如果是使用OnLifecycleEvent并且無添加依賴androidx.lifecycle:lifecycle-compiler注解處理器,則會呼叫此onStateChanged方法,以通知被Lifecycle添加的LifecycleObserver狀態改變,

ClassesInfoCache --> getInfo方法

CallbackInfo getInfo(Class<?> klass) {
    CallbackInfo existing = mCallbackMap.get(klass);
    if (existing != null) {
        return existing;
    }
    existing = createInfo(klass, null);
    return existing;
}

ClassesInfoCache類的getInfo方法,一開始快取里面是沒有的,然后會呼叫createInfo方法進行創建并存盤到快取并回傳其結果,

ClassesInfoCache --> createInfo方法

private CallbackInfo createInfo(Class<?> klass, @Nullable Method[] declaredMethods) {
    ...
    for (Method method : methods) {
        OnLifecycleEvent annotation = method.getAnnotation(OnLifecycleEvent.class);
        if (annotation == null) {
            continue;
        }
        hasLifecycleMethods = true;
        Class<?>[] params = method.getParameterTypes();
        int callType = CALL_TYPE_NO_ARG;
        if (params.length > 0) {
            callType = CALL_TYPE_PROVIDER;
            // 第1個引數必須是LifecycleOwner,否則拋例外,
            if (!params[0].isAssignableFrom(LifecycleOwner.class)) {
                throw new IllegalArgumentException(
                        "invalid parameter type. Must be one and instanceof LifecycleOwner");
            }
        }
        Lifecycle.Event event = annotation.value();

        if (params.length > 1) {
            callType = CALL_TYPE_PROVIDER_WITH_EVENT;
            // 第2個引數必須是Lifecycle.Event,否則拋例外,
            if (!params[1].isAssignableFrom(Lifecycle.Event.class)) {
                throw new IllegalArgumentException(
                        "invalid parameter type. second arg must be an event");
            }
            // 并且OnLifecycleEvent注解的值必須是Lifecycle.Event.ON_ANY,否則拋例外,
            if (event != Lifecycle.Event.ON_ANY) {
                throw new IllegalArgumentException(
                        "Second arg is supported only for ON_ANY value");
            }
        }
        if (params.length > 2) {
            // 超過2個引數,報錯,
            throw new IllegalArgumentException("cannot have more than 2 params");
        }
        ...
    }
    CallbackInfo info = new CallbackInfo(handlerToEvent);
    // 存盤到快取
    mCallbackMap.put(klass, info);
    ...
    return info;
}

說明:

  1. 使用OnLifecycleEvent注解標注方法上,方法要求:方法名稱任意,方法引數可無可1個(必須是LifecycleOwner)、可2個(必須先后是LifecycleOwnerLifecycle.Event、且event必須是Lifecycle.Event.ON_ANY),

總結

代碼流程:

  1. androidxActivityFragment都實作了LifecycleOwner介面,并getLifecycle方法回傳的都是LifecycleRegistry類,
  2. LifecycleRegistryaddObserver方法,會把觀察者狀態的包裝為ObserverWithState,并添加到mObserverMap集合以記錄所有觀察者,
  3. 如果觀察者的狀態一直未到達目標狀態,則一直回圈分發事件,直到相同為止,
  4. 分發事件是由ObserverWithState進行分發的,它統一了所有形式的LifecycleObserver,并處理dispatchEvent方法,用轉換后的LifecycleEventObserver通知被Lifecycle添加的LifecycleObserver狀態改變,

移除觀察者

LifecycleRegistry --> removeObserver方法

@Override
public void removeObserver(@NonNull LifecycleObserver observer) {
    // 當mEnforceMainThread為true時,必須是在主執行緒呼叫,否則拋出例外
    enforceMainThreadIfNeeded("removeObserver");
    // 從map中移除
    mObserverMap.remove(observer);
}

獲取當前狀態

LifecycleRegistry --> getCurrentState方法

@NonNull
@Override
public State getCurrentState() {
    return mState;
}

此狀態是如何被通知的,它又是如何感知生命周期的,我們一起看生命周期感知

生命周期感知

Lifecycle是一個生命周期感知的框架,那么它是如何感知ActivityFragment的生命周期的呢?

Activity

MyActivity繼承關系:MyActivity->AppCompatActivity->FragmentActivity->androidx.activity.ComponentActivity->androidx.core.app.ComponentActivity

androidx.activity.ComponentActivity

androidx.activity.ComponentActivity–> onCreate方法

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    ...
    super.onCreate(savedInstanceState);
    ReportFragment.injectIfNeededIn(this);
    ...
}

androidx.core.app.ComponentActivity

androidx.core.app.ComponentActivity–> onCreate方法

@SuppressLint("RestrictedApi")
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ReportFragment.injectIfNeededIn(this);
}

說明: androidx.activity.ComponentActivity以及它的父類androidx.core.app.ComponentActivity都呼叫了ReportFragment.injectIfNeededIn(this),讓其處理當前Activity的事件分發,

LifecycleDispatcher

LifecycleDispatcher類

class LifecycleDispatcher {

    private static AtomicBoolean sInitialized = new AtomicBoolean(false);

    static void init(Context context) {
        if (sInitialized.getAndSet(true)) {
            return;
        }
        ((Application) context.getApplicationContext())
                .registerActivityLifecycleCallbacks(new DispatcherActivityCallback());
    }

    @SuppressWarnings("WeakerAccess")
    @VisibleForTesting
    static class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks {

        @Override
        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
            ReportFragment.injectIfNeededIn(activity);
        }

        @Override
        public void onActivityStopped(Activity activity) {
        }

        @Override
        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
        }
    }

    private LifecycleDispatcher() {
    }
}

說明:

  1. 添加依賴androidx.lifecycle:lifecycle-process:XXX庫后,內部的startup庫(底層ContentProvider)會呼叫LifecycleDispatcher.init方法進行初始化,然后會注冊一個App級別的ActivityLifecycleCallbacks,監聽所有Activity的生命周期變化,并在onActivityCreated的時候呼叫了ReportFragment.injectIfNeededIn(this)讓其處理當前Activity的事件分發,

問題:

  1. 為什么在App全域內監聽了所有的Activity,還要在androidx.activity.ComponentActivityandroidx.core.app.ComponentActivity內呼叫?

因為可能沒依賴androidx.lifecycle:lifecycle-process:XXX庫, 2. 為什么在androidx.activity.ComponentActivity內呼叫了,還要在其父類androidx.core.app.ComponentActivity內呼叫? 因為MyActivity可能直接繼承的是父類androidx.core.app.ComponentActivity, 3. 上面問題,會導致同一個Activity呼叫了多次,那addObserver增加的觀察者會不會同一個狀態被通知多次? 不會,因為在LifecycleRegistry分發的時候,判斷了,如果要分發的狀態當前的狀態相同,則不操作直接回傳,所以不會被被通知多次, 4. 為什么要用Fragment來實作Activity的事件分發? 因為Fragment能感知生命周期變化,并且Fragment好在Activity中進行增刪,例如MyActivity直接繼承Activity,想要此功能,直接在onCreate方法內呼叫ReportFragment.injectIfNeededIn(this)即可,

ReportFragment

ReportFragment–> injectIfNeededIn方法

public class ReportFragment extends android.app.Fragment {

    public static void injectIfNeededIn(Activity activity) {
        if (Build.VERSION.SDK_INT >= 29) {
            // 29及以上,直接向Activity注冊ActivityLifecycleCallbacks,
            LifecycleCallbacks.registerIn(activity);
        }
        // 添加無布局的Fragment,如果之前已經添加,則不再添加,
        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();
        }
    }   
}

SDK >= 29

@RequiresApi(29)
static class LifecycleCallbacks implements Application.ActivityLifecycleCallbacks {

    static void registerIn(Activity activity) {
        // 注冊ActivityLifecycleCallbacks
        activity.registerActivityLifecycleCallbacks(new LifecycleCallbacks());
    }

    @Override
    public void onActivityCreated(@NonNull Activity activity,
            @Nullable Bundle bundle) {
    }

    @Override
    public void onActivityPostCreated(@NonNull Activity activity,
            @Nullable Bundle savedInstanceState) {
        dispatch(activity, Lifecycle.Event.ON_CREATE);
    }

    @Override
    public void onActivityStarted(@NonNull Activity activity) {
    }

    @Override
    public void onActivityPostStarted(@NonNull Activity activity) {
        dispatch(activity, Lifecycle.Event.ON_START);
    }

    @Override
    public void onActivityResumed(@NonNull Activity activity) {
    }

    @Override
    public void onActivityPostResumed(@NonNull Activity activity) {
        dispatch(activity, Lifecycle.Event.ON_RESUME);
    }

    @Override
    public void onActivityPrePaused(@NonNull Activity activity) {
        dispatch(activity, Lifecycle.Event.ON_PAUSE);
    }

    @Override
    public void onActivityPaused(@NonNull Activity activity) {
    }

    @Override
    public void onActivityPreStopped(@NonNull Activity activity) {
        dispatch(activity, Lifecycle.Event.ON_STOP);
    }

    @Override
    public void onActivityStopped(@NonNull Activity activity) {
    }

    @Override
    public void onActivitySaveInstanceState(@NonNull Activity activity,
            @NonNull Bundle bundle) {
    }

    @Override
    public void onActivityPreDestroyed(@NonNull Activity activity) {
        dispatch(activity, Lifecycle.Event.ON_DESTROY);
    }

    @Override
    public void onActivityDestroyed(@NonNull Activity activity) {
    }
}

SDK >= 29Activity會注冊一個ActivityLifecycleCallbacks監聽此Activity的生命周期變化,會在onCreateonStartonResume 方法被呼叫后onPauseonStoponDestroy 方法被呼叫前分發對應的 Event,同一個Activity可能會注冊多個ActivityLifecycleCallbacks,則同一個狀態會呼叫 dispatch(Activity, Lifecycle.Event)多次,

ReportFragment–> dispatch(Activity, Lifecycle.Event)方法

@SuppressWarnings("deprecation")
static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
    // LifecycleRegistryOwner已被棄用
    if (activity instanceof LifecycleRegistryOwner) {
        ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
        return;
    }

    // ComponentActivity已經實作LifecycleOwner,并getLifecycle方法回傳的是LifecycleRegistry,
    if (activity instanceof LifecycleOwner) {
        Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
        if (lifecycle instanceof LifecycleRegistry) {
            ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
        }
    }
}

由于ComponentActivity已經實作LifecycleOwner,并getLifecycle方法回傳的是LifecycleRegistry,所以我們接下來看一下LifecycleRegistryhandleLifecycleEvent方法,

LifecycleRegistry–> handleLifecycleEvent()方法

public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
    // 當mEnforceMainThread為true時,必須是在主執行緒呼叫,否則拋出例外
    enforceMainThreadIfNeeded("handleLifecycleEvent");
    moveToState(event.getTargetState());
}

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

由于moveToState判斷了同狀態不處理,所以同一個事件多次呼叫handleLifecycleEvent才不會有問題, 我們再來看一下sync方法

LifecycleRegistry–> 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.");
    }
    // 只要未同步,就一直同步,不用if用while的原因,因為同步程序中狀態可能改變了,
    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) {
	        // 小于當前State,呼叫backwardPass向后,
            backwardPass(lifecycleOwner);
        }
        Map.Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
        if (!mNewEventOccurred && newest != null
                && mState.compareTo(newest.getValue().mState) > 0) {
   	        // 大于當前State,呼叫forwardPass向前,
            forwardPass(lifecycleOwner);
        }
    }
    mNewEventOccurred = false;
}

backwardPassforwardPass類似,我們只看forwardPass

LifecycleRegistry–> forwardPass()方法

private void forwardPass(LifecycleOwner lifecycleOwner) {
    Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
            mObserverMap.iteratorWithAdditions();
    // 遍歷所有的觀察者
    while (ascendingIterator.hasNext() && !mNewEventOccurred) {
        Map.Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
        ObserverWithState observer = entry.getValue();
        // 依次同步所有的狀態
        while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
                && mObserverMap.contains(entry.getKey()))) {
            pushParentState(observer.mState);
            final Event event = Event.upFrom(observer.mState);
            if (event == null) {
                throw new IllegalStateException("no event up from " + observer.mState);
            }
            // 觀察者ObserverWithState分發事件,通知被Lifecycle添加的LifecycleObserver狀態改變,
            observer.dispatchEvent(lifecycleOwner, event);
            popParentState();
        }
    }
}

至此通過分發事件,被Lifecycle添加的LifecycleObserver也得到了通知,

SDK < 29 SDK < 29Activity會添加一個無布局的ReportFragment來監聽此Activity的生命周期變化,會在對應的生命周期方法里分發對應的 Event,同一個Activity不會添加多個ReportFragment,所以同一個事件不會呼叫 dispatch( Lifecycle.Event)多次,

ReportFragment–> 生命周期方法

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

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

@Override
public void onResume() {
    super.onResume();
    ...
    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);
    ...
}

ReportFragment–> dispatch(Activity, Lifecycle.Event)方法

private void dispatch(@NonNull Lifecycle.Event event) {
    if (Build.VERSION.SDK_INT < 29) {
        // 僅在SDK 29之前分發,防止重復,
        dispatch(getActivity(), event);
    }
}

由于ReportFragment,在SDK所有版本都有添加,而在SDK >= 29的時候是使用ActivityLifecycleCallbacks處理的分發,所以ReportFragment的分發需要在SDK < 29下,防止重復,

Fragment

androidx.fragment.app.Fragment–> 生命周期方法

public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner,
        ViewModelStoreOwner, HasDefaultViewModelProviderFactory, SavedStateRegistryOwner,
        ActivityResultCaller {

	void performCreate(Bundle savedInstanceState) {
        ...
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
    }

    @SuppressWarnings("ConstantConditions")
    void performStart() {
        ...
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
        ...
    }

    @SuppressWarnings("ConstantConditions")
    void performResume() {
        ...
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
        ...
    }

    @SuppressWarnings("ConstantConditions")
    void performPause() {
        ...
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
        ...
    }

    void performStop() {
        ...
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
        ...
    }

	void performDestroy() {
        ...
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
        ...
    }

androidx.fragment.app.Fragment的實作是直接其生命周期方法內呼叫的handleLifecycleEvent方法進行的分發,

總結

代碼流程:

  1. androidxActivity是使用ReportFragment處理,在其SDK >= 29的時候是使用ActivityLifecycleCallbacks進行的分發,在SDK < 29的時候是使用ReportFragment的生命周期方法進行的分發,
  2. androidxFragment是使用androidx Fragment的生命周期方法進行的分發,
  3. 分發方法最后會呼叫LifecycleRegistryhandleLifecycleEvent方法,如果當前的狀態要分發的狀態不同,則它會同步所有的觀察者
  4. 如果某一個觀察者的狀態一直未到達目標狀態,則一直回圈分發事件,直到相同為止,
  5. 分發事件是由ObserverWithState進行分發的,它統一了所有形式的LifecycleObserver,并處理dispatchEvent方法,用轉換后的LifecycleEventObserver通知被Lifecycle添加的LifecycleObserver狀態改變,

總結

以上就是全面的Jetpack-Lifecycle原始碼了!之后會出Jetpack其它原始碼系列,請及時關注,如果你有什么問題,大家評論區見!

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/380199.html

標籤:其他

上一篇:Retrofit為何成為Android 高工們的最愛?

下一篇:spring cloud spring boot mybatis構建java版 分布式微服務 b2b2c o2o電子商務云商平臺

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more