Android Jetpact Lifecycle 解析

news2024/11/24 17:40:23

认识 Lifecycle

Lifecycle 是什么

LifecycleJetpack 组件库中的一个生命周期感知型组件。在 Lifecycle 出现之前,需要手动从外部宿主(如 Activity、Fragment 或自定义宿主)中将生命周期事件分发到功能组件内部,这势必会造成宿主代码复杂度增加。有了 Lifecycle 的存在,搭建依赖于生命周期变化的业务逻辑变得简单高效,可以用一种统一的方式来监听 Activity、Fragment、甚至是 Process 的生命周期变化,且大大减少了业务代码发生内存泄漏的风险。

事件和状态

Lifecycle 中定义了7种生命周期事件:

  • ON_CREATE: 对应onCreate方法
  • ON_START: 对应onStart方法
  • ON_RESUME: 对应onResume方法
  • ON_PAUSE: 对应onPause方法
  • ON_STOP: 对应onStop方法
  • ON_DESTROY: 对应onDestroy方法
  • ON_ANY: 匹配任何事件

和 5 种生命周期状态:

  • INITIALIZED: Lifecycle 初始化完成,且还未收到 onCreate() 事件时的状态。
  • CREATED:onCreate() 调用之后,或者onStop() 调用之后的状态。
  • STARTED:onStart() 调用之后,或者onPause() 调用之后的状态。
  • RESUMED:onResume() 调用之后,onPause() 调用之前的状态。
  • DESTROYED:onDestory() 调用之后的状态。

事件和状态之间的关系如下图所示,这也是 Lifecycle 分发生命周期状态的流程(记住这张图,后面要考的):
Lifecycle生命周期感知流程

Lifecycle 的设计原理

Lifecycle 整体上采用了观察者模式,主要依赖于三个类:LifecycleOwnerLifecycleRegistryLifecycleObserver

  • LifecycleOwner: 接口,其实现类表示具有生命周期,也就是被观察者。 Activity 和 Fragment 都实现了 LifecycleOwner 接口。
public interface LifecycleOwner {
    /**
     * Returns the Lifecycle of the provider.
     *
     * @return The lifecycle of the provider.
     */
    public val lifecycle: Lifecycle
}
  • LifecycleRegistry: Lifecycle 的实现类,负责管理 LifecycleOwner 的生命周期状态,并将这些状态通知给已注册的观察者。每个 LifecycleOwner 都对应一个 LifecycleRegistry
open class LifecycleRegistry private constructor(
    provider: LifecycleOwner,
    private val enforceMainThread: Boolean
) : Lifecycle() {
...
    private var observerMap = FastSafeIterableMap<LifecycleObserver, ObserverWithState>()
    private var state: State = State.INITIALIZED
    private val lifecycleOwner: WeakReference<LifecycleOwner>

    init {
        lifecycleOwner = WeakReference(provider)
    }
    
    @MainThread
    @Deprecated("Override [currentState].")
    open fun markState(state: State) {
        enforceMainThreadIfNeeded("markState")
        currentState = state
    }
...
}
  • LifecycleObserver: 空接口,表示一个可以观察 LifecycleOwner 生命周期状态的组件,也就是观察者,真正具有使用意义的是它的子接口。
    • LifecycleEventObserver: LifecycleObserver 的子接口,用于监听 Lifecycle 的生命周期变化,可以获取到生命周期事件发生的具体变化。
    • DefaultLifecycleObserver: LifecycleObserver 的子接口,用于监听 Lifecycle 的生命周期变化,对生命周期的每一种事件都提供了独立的方法,适用于只需要知道某些生命周期事件的场景。
public interface LifecycleObserver

public fun interface LifecycleEventObserver : LifecycleObserver {
    /**
     * Called when a state transition event happens.
     *
     * @param source The source of the event
     * @param event The event
     */
    public fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event)
}

public interface DefaultLifecycleObserver : LifecycleObserver {
    /**
     * Notifies that `ON_CREATE` event occurred.
     *
     *
     * This method will be called after the [LifecycleOwner]'s `onCreate`
     * method returns.
     *
     * @param owner the component, whose state was changed
     */
    public fun onCreate(owner: LifecycleOwner) {}

    /**
     * Notifies that `ON_START` event occurred.
     *
     *
     * This method will be called after the [LifecycleOwner]'s `onStart` method returns.
     *
     * @param owner the component, whose state was changed
     */
    public fun onStart(owner: LifecycleOwner) {}

    /**
     * Notifies that `ON_RESUME` event occurred.
     *
     *
     * This method will be called after the [LifecycleOwner]'s `onResume`
     * method returns.
     *
     * @param owner the component, whose state was changed
     */
    public fun onResume(owner: LifecycleOwner) {}

    /**
     * Notifies that `ON_PAUSE` event occurred.
     *
     *
     * This method will be called before the [LifecycleOwner]'s `onPause` method
     * is called.
     *
     * @param owner the component, whose state was changed
     */
    public fun onPause(owner: LifecycleOwner) {}

    /**
     * Notifies that `ON_STOP` event occurred.
     *
     *
     * This method will be called before the [LifecycleOwner]'s `onStop` method
     * is called.
     *
     * @param owner the component, whose state was changed
     */
    public fun onStop(owner: LifecycleOwner) {}

    /**
     * Notifies that `ON_DESTROY` event occurred.
     *
     *
     * This method will be called before the [LifecycleOwner]'s `onDestroy` method
     * is called.
     *
     * @param owner the component, whose state was changed
     */
    public fun onDestroy(owner: LifecycleOwner) {}
}

Lifecycle 整体的设计原理如下:

  1. LifecycleOwner 在创建时会创建一个 Lifecycle 实例。
  2. Lifecycle 实例本质就是 LifecycleRegistry,负责管理 LifecycleOwner 的生命周期状态,并将这些状态通知给已注册的所有观察者。
  3. LifecycleObserver在收到状态变化通知后,可以根据状态变化执行相应的操作。

Lifecycle 的使用

Android 预定义的 LifecycleOwner 有 3 个:Activity(具体实现在 androidx.activity.ComponentActivity)、Fragment 和应用进程级别的 ProcessLifecycleOwner。前两个就不多说了,第3个 ProcessLifecycleOwner 则提供整个应用进程级别的生命周期,能够支持非毫秒级别精度监听应用前后台切换的场景。

Lifecycle 通过 addObserver(LifecycleObserver) 方法注册观察者,支持通过注解或非注解的方式注册观察者,共分为3种方式。其中注解方式已被废弃,在此就不多说了。另外两种方式分别为注册一个 LifecycleEventObserver 观察者和注册一个 DefaultLifecycleObserver 观察者。

/**
 * Annotation that can be used to mark methods on {@link LifecycleObserver} implementations that
 * should be invoked to handle lifecycle events.
 *
 * @deprecated This annotation required the usage of code generation or reflection, which should
 * be avoided. Use {@link DefaultLifecycleObserver} or
 * {@link LifecycleEventObserver} instead.
 */
@SuppressWarnings("unused")
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Deprecated
public @interface OnLifecycleEvent {
    Lifecycle.Event value();
}

注册一个 LifecycleEventObserver 观察者,可以获取到生命周期事件发生的具体变化:

lifecycle.addObserver(object : LifecycleEventObserver {
    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
        when (event) {
            ON_CREATE -> {}
            ON_START -> {}
            ON_RESUME -> {}
            ON_PAUSE -> {}
            ON_STOP -> {}
            ON_DESTROY -> {}
            ON_ANY -> {}
        }
    }
})

注册一个 DefaultLifecycleObserver 观察者,可以按需重写生命周期事件监听:

lifecycle.addObserver(object : DefaultLifecycleObserver {

    override fun onStart(owner: LifecycleOwner) {}

    override fun onStop(owner: LifecycleOwner) {}

    override fun onDestroy(owner: LifecycleOwner) {}
})

对于向 ProcessLifecycleOwner 注册观察者,需要先通过 ProcessLifecycleOwner.get().lifecycle 的方式获取 lifecycle:

ProcessLifecycleOwner.get().lifecycle.addObserver(object: LifecycleEventObserver{
    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
        ...
    }
})

自定义 LifecycleOwner

Lifecycle 的观察者必须绑定到 LifecycleOwner 上,一般来说,我们通过对 Android 预定义的 LifecycleOwner 进行 addObserver 即可,但如果需要自定义 LifecycleOwner,具体步骤就是实现 LifecycleOwner 并在内部将生命周期事件分发给 Lifecycle 实现类 LifecycleRegistry

class MyLifecycleOwner : LifecycleOwner {

    private val mLifecycleRegistry = LifecycleRegistry(this)

    override fun getLifecycle() = mLifecycleRegistry

    fun create() {
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
    }

    fun start() {
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
    }

    fun stop() {
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
    }
    ...
}

解析 Lifecycle

Lifecycle 注册观察者

Lifecycle#addObserver() 最终会分发到其实现类 LifecycleRegistry 中,其中会将观察者和观察者持有的状态包装为一个节点,并且在注册时将观察者状态同步推进到与宿主 LifecycleOwner 相同的状态中。

open class LifecycleRegistry private constructor(
    provider: LifecycleOwner,
    private val enforceMainThread: Boolean
) : Lifecycle() {
...
    //生命周期观察者集合
    private var observerMap = FastSafeIterableMap<LifecycleObserver, ObserverWithState>()
    //当前生命周期状态,默认为初始化状态
    private var state: State = State.INITIALIZED
    //持有生命周期的宿主,弱引用持有,防止内存泄漏
    private val lifecycleOwner: WeakReference<LifecycleOwner>

    init {
        lifecycleOwner = WeakReference(provider)
    }
    
    //添加观察者
    override fun addObserver(observer: LifecycleObserver) {
        //观察者的初始状态:要么是 DESTROYED,要么是 INITIALIZED,确保观察者可以接受到完整的事件流
        val initialState = if (state == State.DESTROYED) State.DESTROYED else State.INITIALIZED
        //将观察者和观察者持有的状态包装为一个节点
        val statefulObserver = ObserverWithState(observer, initialState)
        //加入到观察者集合中
        val previous = observerMap.putIfAbsent(observer, statefulObserver)
        //如果上一步添加成功了,putIfAbsent会返回null
        if (previous != null) {
            return
        }
        //生命周期宿主已被回收,直接return
        val lifecycleOwner = lifecycleOwner.get()
            ?: // it is null we should be destroyed. Fallback quickly
            return
        //当前在添加的观察者数量!=0||正在处理事件
        val isReentrance = addingObserverCounter != 0 || handlingEvent
        //将观察者推进到宿主最新的状态,先获取到最新状态
        var targetState = calculateTargetState(observer)
        addingObserverCounter++
        //如果当前观察者状态小于当前生命周期所在状态&&这个观察者已经被存到了观察者列表中
        //while一直循环,直到观察者状态同步到当前生命周期所在状态
        while (statefulObserver.state < targetState && observerMap.contains(observer)
        ) {
            //保存当前的生命周期状态
            pushParentState(statefulObserver.state)
            //返回当前生命周期状态对应的接下来的事件序列
            val event = Event.upFrom(statefulObserver.state)
                ?: throw IllegalStateException("no event up from ${statefulObserver.state}")
            //分发事件
            statefulObserver.dispatchEvent(lifecycleOwner, event)
            //移除当前的生命周期状态
            popParentState()
            //再次获得当前的最新状态
            // mState / subling may have been changed recalculate
            targetState = calculateTargetState(observer)
        }
        //处理一遍事件,保证事件同步
        if (!isReentrance) {
            // we do sync only on the top level.
            sync()
        }
        addingObserverCounter--
    }
    
    //移除观察者
    override fun removeObserver(observer: LifecycleObserver) {
        observerMap.remove(observer)
    }
    
    //观察者及其观察状态
    internal class ObserverWithState(observer: LifecycleObserver?, initialState: State) {
        var state: State
        var lifecycleObserver: LifecycleEventObserver

        init {
            //用适配器包装观察者,实现对不同类型观察者的统一分发
            lifecycleObserver = Lifecycling.lifecycleEventObserver(observer!!)
            state = initialState
        }

        fun dispatchEvent(owner: LifecycleOwner?, event: Event) {
            val newState = event.targetState
            state = min(state, newState)
            //通知观察者
            lifecycleObserver.onStateChanged(owner!!, event)
            state = newState
        }
    }
...
}

Lifecycle 注册观察者的逻辑就是上面这些了,主要步骤如下:

  1. 初始化观察者的状态。
  2. 将观察者和观察者持有的状态包装为一个节点。
  3. 将观察者和其状态加入到 map 集合中。
  4. 获取当前 LifecycleOwner 生命周期状态。
  5. while 循环,将观察者状态同步推进到与宿主 LifecycleOwner 相同的状态。

Lifecycle 适配不同类型的观察者

上面说到了注册观察者的时候会将观察者和观察者持有的状态包装为一个节点 ObserverWithState,而在 ObserverWithState 中会将外部传入的所有 LifecycleObserver 通过 Lifecycling 包装成 LifecycleEventObserver 对象。之所以要这么做就是为了适配不同类型的观察者,Lifecycling 就是适配层。

  1. LifecycleObserver 本身是个空接口,实际使用的是它两个子接口 LifecycleEventObserverDefaultLifecycleObserver,开发者自己实现的自定义 Observer 可能同时实现了这两个接口或者实现了任一接口,LifecycleRegistry 必须在有事件触发的时候通知观察者存在的所有接口方法。
  2. 上面讲到注册观察者的方式还有注解的方式(虽然现已被废弃),但是这种方式下就需要通过反射来实现事件通知了。

Lifecycling 作为适配层,其作用就是对外部传入的 Observer 进行类型判断、接口回调、反射调用等一系列操作,将这一系列的逻辑给封装起来,对传入的 Observer 统一包装成 LifecycleEventObserver 对象,仅仅开放一个 onStateChanged 方法即可让 LifecycleRegistry 完成整个事件分发,从而使得整个流程会更加清晰明了且职责分明。

public object Lifecycling {
    @JvmStatic
    @Suppress("DEPRECATION")
    public fun lifecycleEventObserver(`object`: Any): LifecycleEventObserver {
        val isLifecycleEventObserver = `object` is LifecycleEventObserver
        val isDefaultLifecycleObserver = `object` is DefaultLifecycleObserver
        // 1. 观察者同时实现 LifecycleEventObserver 和 DefaultLifecycleObserver
        if (isLifecycleEventObserver && isDefaultLifecycleObserver) {
            return DefaultLifecycleObserverAdapter(
                `object` as DefaultLifecycleObserver,
                `object` as LifecycleEventObserver
            )
        }
        // 2. 观察者只实现 DefaultLifecycleObserver
        if (isDefaultLifecycleObserver) {
            return DefaultLifecycleObserverAdapter(`object` as DefaultLifecycleObserver, null)
        }
        // 3. 观察者只实现 LifecycleEventObserver
        if (isLifecycleEventObserver) {
            return `object` as LifecycleEventObserver
        }
        // 4. 观察者使用注解方式
        val klass: Class<*> = `object`.javaClass
        val type = getObserverConstructorType(klass)
        if (type == GENERATED_CALLBACK) {
            val constructors = classToAdapters[klass]!!
            if (constructors.size == 1) {
                val generatedAdapter = createGeneratedAdapter(
                    constructors[0], `object`
                )
                return SingleGeneratedAdapterObserver(generatedAdapter)
            }
            val adapters: Array<GeneratedAdapter> = Array(constructors.size) { i ->
                createGeneratedAdapter(constructors[i], `object`)
            }
            return CompositeGeneratedAdaptersObserver(adapters)
        }
        // 反射调用
        return ReflectiveGenericLifecycleObserver(`object`)
    }
}

DefaultLifecycleObserverAdapter 实现了 LifecycleEventObserver 接口,用于在收到 Lifecycle 生命周期事件状态变化时,对两个构造参数 DefaultLifecycleObserverLifecycleEventObserver 进行事件转发。

internal class DefaultLifecycleObserverAdapter(
    private val defaultLifecycleObserver: DefaultLifecycleObserver,
    private val lifecycleEventObserver: LifecycleEventObserver?
) : LifecycleEventObserver {
    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
        when (event) {
            Lifecycle.Event.ON_CREATE -> defaultLifecycleObserver.onCreate(source)
            Lifecycle.Event.ON_START -> defaultLifecycleObserver.onStart(source)
            Lifecycle.Event.ON_RESUME -> defaultLifecycleObserver.onResume(source)
            Lifecycle.Event.ON_PAUSE -> defaultLifecycleObserver.onPause(source)
            Lifecycle.Event.ON_STOP -> defaultLifecycleObserver.onStop(source)
            Lifecycle.Event.ON_DESTROY -> defaultLifecycleObserver.onDestroy(source)
            Lifecycle.Event.ON_ANY ->
                throw IllegalArgumentException("ON_ANY must not been send by anybody")
        }
        lifecycleEventObserver?.onStateChanged(source, event)
    }
}

Lifecycle 分发生命周期事件

在注册观察者的时候,将观察者状态同步推进到与宿主 LifecycleOwner 相同的状态,用的是 while 循环,每一次获取当前状态接下来的事件并进行事件分发,一次一步,直到状态同步。

public enum class Event {
    public companion object {
            /**
             * Returns the [Lifecycle.Event] that will be reported by a [Lifecycle]
             * leaving the specified [Lifecycle.State] to a higher state, or `null`
             * if there is no valid event that can move up from the given state.
             *
             * @param state the lower state that the returned event will transition up from
             * @return the event moving up the lifecycle phases from state
             */
            @JvmStatic
            public fun upFrom(state: State): Event? {
                return when (state) {
                    State.INITIALIZED -> ON_CREATE
                    State.CREATED -> ON_START
                    State.STARTED -> ON_RESUME
                    else -> null
                }
            }
    }
}

结合 Lifecycle 分发生命周期状态的流程图:
Lifecycle生命周期感知流程

如果在 Activity onResume 之后向其添加了一个 LifecycleEventObserver,此时观察者初始状态是 INITIALIZED,需要同步到与宿主 LifecycleOwner 相同的状态,也就是RESUMED,观察者会依次收到 ON_CREATE、ON_START、ON_RESUME 三个Event事件。

当宿主 LifecycleOwner 生命周期发生变化时,会将生命周期事件分发到 LifecycleRegistry#handleLifecycleEvent(Lifecycle.Event),将观察者的状态回调到最新的状态上。

    //分发生命周期事件
    open fun handleLifecycleEvent(event: Event) {
        moveToState(event.targetState)
    }

    private fun moveToState(next: State) {
        if (state == next) {
            return
        }
        check(!(state == State.INITIALIZED && next == State.DESTROYED)) {
            "no event down from $state in component ${lifecycleOwner.get()}"
        }
        state = next
        if (handlingEvent || addingObserverCounter != 0) {
            newEventOccurred = true
            // we will figure out what to do on upper level.
            return
        }
        handlingEvent = true
        //状态同步
        sync()
        handlingEvent = false
        if (state == State.DESTROYED) {
            observerMap = FastSafeIterableMap()
        }
    }
    
    private fun sync() {
        val lifecycleOwner = lifecycleOwner.get()
            ?: throw IllegalStateException(
                "LifecycleOwner of this LifecycleRegistry is already " +
                    "garbage collected. It is too late to change lifecycle state."
            )
        while (!isSynced) {
            newEventOccurred = false
            if (state < observerMap.eldest()!!.value.state) {
                //状态回退
                backwardPass(lifecycleOwner)
            }
            val newest = observerMap.newest()
            if (!newEventOccurred && newest != null && state > newest.value.state) {
                //状态前进
                forwardPass(lifecycleOwner)
            }
        }
        newEventOccurred = false
    }
    
    private fun forwardPass(lifecycleOwner: LifecycleOwner) {
        @Suppress()
        val ascendingIterator: Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> =
            observerMap.iteratorWithAdditions()
        while (ascendingIterator.hasNext() && !newEventOccurred) {
            val (key, observer) = ascendingIterator.next()
            while (observer.state < state && !newEventOccurred && observerMap.contains(key)
            ) {
                pushParentState(observer.state)
                val event = Event.upFrom(observer.state)
                    ?: throw IllegalStateException("no event up from ${observer.state}")
                observer.dispatchEvent(lifecycleOwner, event)
                popParentState()
            }
        }
    }

首先更新状态 state,然后通过 sync() 方法将状态同步到所有观察者,sync() 方法在添加观察者时也被调用过。在 sync() 方法中,状态需要回退则调用 backwardPass 方法,状态需要前进则调用 forwardPass 方法。两个方法逻辑相似,这边就只贴出了 forwardPass 方法,来看一下如何处理状态前进的。可以发现里面使用了两层 while 循环,外层 while 循环遍历所有观察者,内层 while 循环与注册观察者时状态同步的 while 循环内容一致,每一次获取当前状态接下来的事件并进行事件分发,一次一步,直到状态同步。

最终 observer.dispatchEvent 是通过 ObserverWithState#dispatchEvent() 分发事件,我们已经知道 ObserverWithState 里使用了适配器模式对 Observer 统一包装成 LifecycleEventObserver 对象,仅仅开放一个 onStateChanged 方法,ObserverWithState#dispatchEvent() 里就是通过 lifecycleObserver.onStateChanged 通知到观察者,后续就是上一点提到的 Lifecycling 适配层的逻辑了。

Lifecycle 感知 Activity 生命周期

知道了怎么注册的观察者以及如何将生命周期事件分发到观察者,最后来看一下 Lifecycle 是如何感知到宿主 LifecycleOwner 的生命周期进而继续后续的操作的。

上面讲到当宿主 LifecycleOwner 生命周期发生变化时,会将生命周期事件分发到 LifecycleRegistry#handleLifecycleEvent(Lifecycle.Event),这不就简单了,在宿主 LifecycleOwner 生命周期的相关方法直接调用不就好了。

handleLifecycleEvent调用处

通过查看 LifecycleRegistry#handleLifecycleEvent 的调用,可以看到在 DialogFragmentFragmenActivity 里就是通过在生命周期的相关方法里直接调用 LifecycleRegistry#handleLifecycleEvent(Lifecycle.Event)将生命周期事件分发的,但是并没有出现我们常用的 ComponentActivity,这是因为上述这种方法会造成对基类的入侵,使得基类越发膨胀,所以在 ComponentActivity 中使用了 ReportFragment 承载 Lifecycle 在 activity 的具体逻辑。

感知宿主生命周期使用 ReportFragment,管理生命周期状态并将状态通知观察者使用 LifecycleRegistry,适配观察者使用 Lifecycling,这一整套流程行云流水清晰明了且职责分明。

public class ComponentActivity extends androidx.core.app.ComponentActivity implements LifecycleOwner ...{
    private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

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

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

通过 ReportFragment#injectIfNeededIn(Activity) 接收 Activity。

open class ReportFragment() : android.app.Fragment() {
    companion object {
        @JvmStatic
        fun 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
            val manager = activity.fragmentManager
            if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
                manager.beginTransaction().add(ReportFragment(), REPORT_FRAGMENT_TAG).commit()
                // Hopefully, we are the first to make a transaction.
                manager.executePendingTransactions()
            }
        }
    }
}
  • 第一种情况:在sdk29以下,通过向 Activity 添加一个空白界面的 Fragment,间接获得 Activity 的各个生命周期事件的回调通知。
  • 第二种情况:在sdk29及以上,通过向 Activity 注册生命周期回调的方式来监听。这里应该还牵扯到对旧版本 ProcessLifecycleOwner 和 support 库的兼容,所以此时也会同时执行第一种情况的操作。

之所以这么区分是因为 registerActivityLifecycleCallbacks 中的 onActivityPostXXXonActivityPreXXX 等方法是sdk29时新添加的方法。

    @RequiresApi(29)
    internal class LifecycleCallbacks : Application.ActivityLifecycleCallbacks {
        override fun onActivityCreated(
            activity: Activity,
            bundle: Bundle?
        ) {}

        override fun onActivityPostCreated(
            activity: Activity,
            savedInstanceState: Bundle?
        ) {
            dispatch(activity, Lifecycle.Event.ON_CREATE)
        }

        override fun onActivityStarted(activity: Activity) {}

        override fun onActivityPostStarted(activity: Activity) {
            dispatch(activity, Lifecycle.Event.ON_START)
        }

        override fun onActivityResumed(activity: Activity) {}

        override fun onActivityPostResumed(activity: Activity) {
            dispatch(activity, Lifecycle.Event.ON_RESUME)
        }

        override fun onActivityPrePaused(activity: Activity) {
            dispatch(activity, Lifecycle.Event.ON_PAUSE)
        }

        override fun onActivityPaused(activity: Activity) {}

        override fun onActivityPreStopped(activity: Activity) {
            dispatch(activity, Lifecycle.Event.ON_STOP)
        }

        override fun onActivityStopped(activity: Activity) {}

        override fun onActivitySaveInstanceState(
            activity: Activity,
            bundle: Bundle
        ) {}

        override fun onActivityPreDestroyed(activity: Activity) {
            dispatch(activity, Lifecycle.Event.ON_DESTROY)
        }

        override fun onActivityDestroyed(activity: Activity) {}

        companion object {
            @JvmStatic
            fun registerIn(activity: Activity) {
                activity.registerActivityLifecycleCallbacks(LifecycleCallbacks())
            }
        }
    }

一些小细节,在sdk29及以上,通过向 Activity 注册生命周期回调的方式来监听时,会在 Activity 的 onCreate、onStart、onResume 等方法被调用后发送相应的 Event 事件,并在 onPause、onStop、onDestroy 等方法被调用前发送相应的 Event 事件。

Lifecycle 的运用实践案例

Lifecycle 作为 JetPack 的基石,在 JetPack 里已有了许多的运用实践:

  1. LifecycleOwner.lifecycleScope,具有生命周期感知的协程作用域,当宿主 destroy 时,会自动取消协程。
  2. LiveData,具有生命周期感知能力,当宿主状态活跃时(状态至少为 STARTED),才会发送数据,同时当宿主 destroy 时,会自动移除观察者。
  3. Flow#flowWithLifecycle(),当宿主状态活跃时(默认状态至少为 STARTED),启动一个新协程用于接收 flow 数据,当宿主状态不活跃时,取消该协程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2114835.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GEE数据集:加拿大卫星森林资源调查 (SBFI)-2020 年加拿大森林覆盖、干扰恢复、结构、物种、林分年龄以及 1985-2020 年林分替代干扰的信息

目录 简介 数据集后处理 数据下载链接 矢量属性 代码 代码链接 引用 许可 网址推荐 0代码在线构建地图应用 机器学习 加拿大卫星森林资源调查 (SBFI) 简介 卫星森林资源清查&#xff08;SBFI&#xff09;提供了 2020 年加拿大森林覆盖、干扰恢复、结构、物种、林分…

6.3图的遍历

图的遍历是指从某点出发,按照某种搜索方式沿着边访问图中所有节点 图的遍历算法主要有两种:广度优先,深度优先 都需要辅助数组visited[]来记录节点是否被访问过 6.3.1广度优先搜索 like层次遍历,需要辅助队列 代码实现 #include<stdio.h> #define maxnum 15 bool vi…

解决Win10版Township进度保存问题

解决Win10版Township进度保存问题 问题描述问题分析解决步骤1.WinR打开运行&#xff0c;输入regedit点击确定打开注册表2.进入注册表“计算机\HKEY_CURRENT_USER\Software\Classes\LocalSettings\Software\Microsoft\Windows\CurrentVersion\AppContainer\Mappings”目录3.在这…

算法题之水壶问题

水壶问题 有两个水壶&#xff0c;容量分别为 x 和 y 升。水的供应是无限的。确定是否有可能使用这两个壶准确得到 target 升。 你可以&#xff1a; 装满任意一个水壶清空任意一个水壶将水从一个水壶倒入另一个水壶&#xff0c;直到接水壶已满&#xff0c;或倒水壶已空。 示…

LabVIEW制系统开发流程介绍

在开发一个LabVIEW电机控制系统时&#xff0c;尤其是涉及多种类型的电机并需实现本地与远程控制时&#xff0c;合理的开发顺序是确保项目高效完成且返工最少的关键。下面介绍如何按照系统需求分阶段开发&#xff0c;从而保障开发的速度与质量&#xff0c;减少返工的风险。 开发…

企业大模型落地的“最后一公里”攻略

一、大模型落地的行业现状与前景 大模型在多个行业展现出强大的应用潜力。在金融行业&#xff0c;沉淀了大量高质量数据&#xff0c;各金融平台用户数以亿计&#xff0c;交易数据浩如烟海。利用大模型分析处理这些数据&#xff0c;金融机构可以预测用户行为偏好&#xff0c;更…

CMake/C++:一个日志库spdlog

项目仓库 GitHub - gabime/spdlog: Fast C logging library.Fast C logging library. Contribute to gabime/spdlog development by creating an account on GitHub.https://github.com/gabime/spdlog 知乎参考贴 https://zhuanlan.zhihu.com/p/674073158 先将仓库clone一下 然…

LabVIEW如何确保采集卡稳定运行

在LabVIEW开发中&#xff0c;如何确保硬件采集卡稳定运行&#xff0c;特别是长期采集电压信号&#xff0c;是系统稳定性的重要考虑因素。用户在使用采集卡时&#xff0c;可能需要频繁进行开始、停止和重新采集的操作&#xff0c;这对硬件和软件提出了高要求。下面介绍实现长期稳…

大数据开发职场:理性分析拖延

你有没有遇到过这样的情况&#xff1a;周四晚上&#xff0c;室友兴高采烈地邀请你去看最新上映的大片&#xff0c;而你正在奋战一份截止日期为下周一的化学作业。这个看似简单的选择&#xff0c;实际上隐藏着一个深刻的人生哲学问题。 目录 5秒钟抓住你的注意力深入探讨&#x…

YOLOv8/v10+DeepSORT多目标车辆跟踪(车辆检测/跟踪/车辆计数/测速/禁停区域/绘制进出线/绘制禁停区域/车道车辆统计)

01&#xff1a;YOLOv8 DeepSort 车辆跟踪 该项目利用YOLOv8作为目标检测模型&#xff0c;DeepSort用于多目标跟踪。YOLOv8负责从视频帧中检测出车辆的位置&#xff0c;而DeepSort则负责关联这些检测结果&#xff0c;从而实现车辆的持续跟踪。这种组合使得系统能够在视频流中准…

连接池的设计与实现-0基础Go语言版

为什么需要连接池&#xff1f; 假设现在没有连接池&#xff0c;每次建立一个新的连接&#xff0c;都需要消耗一定的时间开销&#xff08;必要时会使用TCP三次握手&#xff09;。因此&#xff0c;连接的创建和销毁是一件非常昂贵的操作。尤其是在高并发场景下&#xff0c;可能会…

一场 Kafka CRC 异常引发的血案

一、问题概述 客户的生产环境突然在近期间歇式的收到了Kafka CRC的相关异常&#xff0c;异常内容如下 Record batch for partition skywalking-traces-0 at offset 292107075 is invalid, cause: Record is corrupt (stored crc 1016021496, compute crc 1981017560) 报错…

时间同步服务

多主机协作工作时&#xff0c;各个主机的时间同步很重要&#xff0c;时间不一致会造成很多重要应用的故障&#xff0c;如&#xff1a;加密协 议&#xff0c;日志&#xff0c;集群等。 利用NTP&#xff08;Network Time Protocol&#xff09; 协议使网络中的各个计算机时间达到…

网络安全运维培训一般多少钱

在当今数字化时代&#xff0c;网络安全已成为企业和个人关注的焦点。而网络安全运维作为保障网络安全的重要环节&#xff0c;其专业人才的需求也日益增长。许多人都对网络安全运维培训感兴趣&#xff0c;那么&#xff0c;网络安全运维培训一般多少钱呢? 一、影响网络安全运维培…

RISC-V (十一)软件定时器

主要的思想&#xff1a;硬件定时器是由硬件的定时器设备触发的。软件定时器在硬件定时器的基础上由软件控制实现多个定时器的效果。主要的思路是在trap_handler函数中加入软件代码&#xff0c;使其在设定的时间点 去执行想要执行的功能函数。 定时器的分类 硬件定时器&#xf…

Linux 复制目录和文件

概述 cp 命令主要可用于复制文件或目录。 cp 是单词 copy 的缩写。 语法 cp 命令的语法如下: cp [选项] source dest。即复制 source 文件到 dest。 该命令支持的选项有: 选项说明-r递归复制整个文件夹-i若目标文件已经存在,则会询问是否覆盖-p保留源文件或目录的所有属性…

安卓玩机工具-----ADB方式的刷机玩机工具“秋之盒”’ 测试各项功能预览

秋之盒 安卓玩机工具-秋之盒是一款ADB刷机工具箱&#xff0c;基于谷歌ADB的一款绿色安装&#xff0c;具备了海量扩展模块,支持ADB刷机救砖、一键激活黑域、adb指令修复等功能&#xff0c;是一款开源、免费、易用的手机刷机工具&#xff01; 并且是一款开源、免费、易用的图形化…

OneHotEncoder一个不太合理的地方

OneHotEncoder&#xff0c;在Xtrain上fit&#xff0c;在Xtest上transform 如果遇到某个值出现在Xtest&#xff0c;而没有在Xtrain出现过时&#xff0c;会抛出如下错误&#xff1a; OneHotEncoder Found unknown categories [xxx] in column xx during transform OneHotEncoder …

简单实用的php全新实物商城系统

免费开源电商系统,提供灵活的扩展特性、高度自动化与智能化、创新的管理模式和强大的自定义模块,让电商用户零成本拥有安全、高效、专业的移动商城。 代码是全新实物商城系统源码版。 代码下载

Prometheus 服务监控

官网&#xff1a;https://prometheus.io Prometheus 是什么 Prometheus 是一个开源的系统监控和报警工具&#xff0c;专注于记录和存储时间序列数据&#xff08;time-series data&#xff09;。它最初由 SoundCloud 开发&#xff0c;并已成为 CNCF&#xff08;云原生计算基金会…