Lifecycle 解析

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 关系则如图所示:
image

我们先来看看 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,"进入后台")
        }
    })

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容