Lifecycle 解析

1,145 阅读4分钟

Tips: 本文基于 lifecycle-2.4.0 分析。截止完成时 Lifecycle 组件最新版本为 2.4.0。

2.4.0 版本变更

  • 废弃了 @OnLifecycleEvent。应改用 LifecycleEventObserverDefaultLifecycleObserver
  • androidx.lifecycle:lifecycle-runtime-ktx 添加了新的协程 API:
    • Lifecycle.repeatOnLifecycle - 当 Lifecycle 至少处于某个状态时,此 API 会在协程中执行代码块。当 Lifecycle 进入和退出目标状态时,该代码块将取消并重新启动;
    • Flow.flowWithLifecycle - 当 Lifecycle 至少处于某个状态时,此 API 会发出来自上游 flow 的值。
  • 现在,lifecycle-process 使用 androidx.startup 来初始化 ProcessLifecycleOwner。之前此操作是由 androidx.lifecycle.ProcessLifecycleOwnerInitializer 完成的。
    dependencies {
        def lifecycle_version = "2.4.0"
        def arch_version = "2.1.0"

        // ViewModel
        implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
        // ViewModel utilities for Compose
        implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version"
        // LiveData
        implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
        // Lifecycles only (without ViewModel or LiveData)
        implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"

        // Saved state module for ViewModel
        implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"

        // Annotation processor
        kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
        // alternately - if using Java8, use the following instead of lifecycle-compiler
        implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"

        // optional - helpers for implementing LifecycleOwner in a Service
        implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"

        // optional - ProcessLifecycleOwner provides a lifecycle for the whole application process
        implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"

        // optional - ReactiveStreams support for LiveData
        implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycle_version"

        // optional - Test helpers for LiveData
        testImplementation "androidx.arch.core:core-testing:$arch_version"
    }

今天我们重点来看 androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version 中的内容。

LifecycleOwner LifecycleObserver 和 Lifecycle

Lifecyle 组件拥有三大基石:Lifecycle,LifecycleObserver 以及 LifecycleOwner。
LifecycleObserver 顾名思义代表的是生命周期中的观察者:

    public interface LifecycleObserver {

    }

LifecycleOwner 则是生命周期的拥有者,在 Android 中 Fragment 和 ComponentActivity 都实现了此接口:

    public interface LifecycleOwner {
        @NonNull
        Lifecycle getLifecycle();
    }

最后就是 Lifecycle,每个 LifecycleOwner 都会持有 Lifecycle 对象,通过它我们才可以获得当前的所处的生命周期,增加、删除观察者:

    public abstract class Lifecycle {
        public abstract void addObserver(@NonNull LifecycleObserver observer);

        public abstract void removeObserver(@NonNull LifecycleObserver observer);

        public abstract State getCurrentState();
    }

Lifecycle 类里还定义了两个枚举类 EventState

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

在 Event 类中提供了 upFrom()upTo()downFrom()downTo() 以及 getTargetState() 方法,分别用来获取当前 State 向前、向后转换所对应的 Event 以及当前 Event 所对应的 State:

    @Nullable
    public static Event upFrom(@NonNull State state) {
        switch (state) {
            case INITIALIZED:
                return ON_CREATE;
            case CREATED:
                return ON_START;
            case STARTED:
                return ON_RESUME;
            default:
                return null;
        }
    }

    @Nullable
    public static Event upTo(@NonNull State state) {
        switch (state) {
            case CREATED:
                return ON_CREATE;
            case STARTED:
                return ON_START;
            case RESUMED:
                return ON_RESUME;
            default:
                return null;
        }
    }
        
    @NonNull
    public State getTargetState() {
        switch (this) {
            case ON_CREATE:
            case ON_STOP:
                return State.CREATED;
            case ON_START:
            case ON_PAUSE:
                return State.STARTED;
            case ON_RESUME:
                return State.RESUMED;
            case ON_DESTROY:
                return State.DESTROYED;
            case ON_ANY:
                break;
        }
        throw new IllegalArgumentException(this + " has no target state");
    }

State 类中提供了 isAtLeast() 方法,用来判断当前 State 是否高于给定的最低 State:

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

整体的 State 与 Event 关系则如图所示:

我们先来看看 Fragment 和 ComponentActivity 中 getLifecycle() 的实现:

    LifecycleRegistry mLifecycleRegistry;

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

LifecycleRegistry 是 Lifecycle 的实现类,有一段需要注意的代码是:

    @Override
    public void addObserver(@NonNull LifecycleObserver observer) {
        enforceMainThreadIfNeeded("addObserver");
        State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
        // 看这里
        ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
        ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
        ...
        // 看这里
        State targetState = calculateTargetState(observer);
        mAddingObserverCounter++;
        ...
        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);
            }
            statefulObserver.dispatchEvent(lifecycleOwner, event);
            popParentState();
            // mState / subling may have been changed recalculate
            targetState = calculateTargetState(observer);
        }
        ...
    }
  • 这段代码表明,即使我们在 State 为 RESUMED 时添加订阅者,该订阅者同样能够接收到完整的 ON_CREATE,ON_START,ON_RESUME 事件流。

在 2.4.0 以前的版本,Lifecycle 可以搭配 OnLifecycleEvent 注解来使用:

    public class MLifecycleObserver implements LifecycleObserver {
        @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
        public void onCreate() { Log.d(TAG, "onCreate"); }
    }

如果是 Java8 的话,可以通过实现 DefaultLifecycleObserver 来使用。而到了 2.4.0 版本后,OnLifecycleEvent 已经被标记废弃,需要替换成实现 DefaultLifecycleObserverLifecycleEventObserver

如果同时实现了 DefaultLifecycleObserverLifecycleEventObserver 两个接口,那么会先触发 DefaultLifecycleObserver,然后再触发 LifecycleEventObserver。 万事具备,只欠东风了。Lifecyle 如何与组件绑定,从而获取到生命周期的变化的呢? 让我们看看 ComponentActivity 的实现:

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

ReportFragment.injectIfNeededIn(this) 就是关键所在:

public static void injectIfNeededIn(Activity activity) {
        if (Build.VERSION.SDK_INT >= 29) {
            // On API 29+, we can register for the correct Lifecycle callbacks directly
            LifecycleCallbacks.registerIn(activity);
        }
        // Prior to API 29 and to maintain compatibility with older versions of
        // ProcessLifecycleOwner (which may not be updated when lifecycle-runtime is updated and
        // need to support activities that don't extend from FragmentActivity from support lib),
        // use a framework fragment to get the correct timing of Lifecycle events
        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();
        }
    }

repeatOnLifecycle & flowWithLifecycle

flowWithLifecycle 实际上就是调用 repeatOnLifecycle:

    public fun <T> Flow<T>.flowWithLifecycle(
        lifecycle: Lifecycle,
        minActiveState: Lifecycle.State = Lifecycle.State.STARTED
    ): Flow<T> = callbackFlow {
        lifecycle.repeatOnLifecycle(minActiveState) {
            this@flowWithLifecycle.collect {
                send(it)
            }
        }
        close()
    }

repeatOnLifecycle 实现如下:

    public suspend fun Lifecycle.repeatOnLifecycle(
        state: Lifecycle.State,
        block: suspend CoroutineScope.() -> Unit
    ) {
        require(state !== Lifecycle.State.INITIALIZED) {
            "repeatOnLifecycle cannot start work with the INITIALIZED lifecycle state."
        }

        if (currentState === Lifecycle.State.DESTROYED) {
            return
        }

        // This scope is required to preserve context before we move to Dispatchers.Main
        coroutineScope {
            withContext(Dispatchers.Main.immediate) {
                // Check the current state of the lifecycle as the previous check is not guaranteed
                // to be done on the main thread.
                if (currentState === Lifecycle.State.DESTROYED) return@withContext

                // Instance of the running repeating coroutine
                var launchedJob: Job? = null

                // Registered observer
                var observer: LifecycleEventObserver? = null
                try {
                    // Suspend the coroutine until the lifecycle is destroyed or
                    // the coroutine is cancelled
                    suspendCancellableCoroutine<Unit> { cont ->
                        // Lifecycle observers that executes `block` when the lifecycle reaches certain state, and
                        // cancels when it falls below that state.
                        val startWorkEvent = Lifecycle.Event.upTo(state)
                        val cancelWorkEvent = Lifecycle.Event.downFrom(state)
                        val mutex = Mutex()
                        observer = LifecycleEventObserver { _, event ->
                            if (event == startWorkEvent) {
                                // Launch the repeating work preserving the calling context
                                launchedJob = this@coroutineScope.launch {
                                    // Mutex makes invocations run serially,
                                    // coroutineScope ensures all child coroutines finish
                                    mutex.withLock {
                                        coroutineScope {
                                            block()
                                        }
                                    }
                                }
                                return@LifecycleEventObserver
                            }
                            if (event == cancelWorkEvent) {
                                launchedJob?.cancel()
                                launchedJob = null
                            }
                            if (event == Lifecycle.Event.ON_DESTROY) {
                                cont.resume(Unit)
                            }
                        }
                        this@repeatOnLifecycle.addObserver(observer as LifecycleEventObserver)
                    }
                } finally {
                    launchedJob?.cancel()
                    observer?.let {
                        this@repeatOnLifecycle.removeObserver(it)
                    }
                }
            }
        }
    }

ProcessLifecycleOwner

Lifecycle 还提供了一个 ProcessLifecycleOwner 用来获取整个 application 的生命周期,在这个 Lifecycle 中,ON_CREATE 只会在创建时出现一次,并且永远不会出现 ON_DESTROY 事件。ON_START,ON_RESUME 会在第一个 activity 触发时发送;而 ON_PAUSE,ON_STOP 会在最后一个 activity 触发后延迟一小段时间后发出。各位可以思考下这是为什么?愿意很简单,是为了避免因 configerationChanged 导致销毁重建而发出错误的 Event。
那么再有需要监控应用前后台的场景时就可以这么做了:

    ProcessLifecycleOwner.get().lifecycle.addObserver(object : DefaultLifecycleObserver {
        override fun onStart(owner: LifecycleOwner) {
            super.onStart(owner)
            Log.e(TAG,"进入前台")
        }

        override fun onStop(owner: LifecycleOwner) {
            super.onStop(owner)
            Log.e(TAG,"进入后台")
        }
    })