Android Jetpack组件架构:Lifecycle的使用 和 原理

Android Jetpack组件架构:Lifecycle的使用和原理

导言

作为Jetpack中关于生命周期管理的核心组件,Lifecycle组件是其他比如LiveDate和ViewModel等组件的基础,本篇文章主要就将介绍关于Lifecycle的使用和它的运作原理。

Lifecycle的使用

我们先从Google官网上拉一段示例代码:

kotlin 复制代码
class MyObserver : DefaultLifecycleObserver {
    override fun onResume(owner: LifecycleOwner) {
        connect()
    }

    override fun onPause(owner: LifecycleOwner) {
        disconnect()
    }
}

myLifecycleOwner.getLifecycle().addObserver(MyObserver())

可以看到这段代码首先是实现了DefaultLifecycleObserver接口,并且实现了其中的两个方法,这两个方法就是在Lifecycle组件的生命状态发生改变的时候触发的,具体来说它的作用和Activity中的各种生命周期的回调差不多。那为什么还要引入Lifecycle组件呢?原因就是为了解耦,这些年来Google越来越推崇MVVM架构,这个架构的核心思想之一就是将Activity进行解耦,尝试不要再Activity中加入过多的业务代码,要是我们直接将方法写在Activity中的话会显得整个Activity都很臃肿,切不利于我们管理,所以引入了Lifecycle组件来帮助我们管理与生命周期相关的回调。 除此之外,Lifecycle组件也是许多jetpack之中其他组件的基础。

Lifecycle的原理

Lifecycle的状态和事件

这整个Lifecycle中有两个重要的信息,一个是Lifecycle当前的状态,另一个Lifecycle状态变化而引起的事件,具体如下所示:

我们也可以在源码中找到:

kotlin 复制代码
    public enum class State {
        DESTROYED,
        INITIALIZED,
        CREATED,
        STARTED,
        RESUMED;

        public fun isAtLeast(state: State): Boolean {
            return compareTo(state) >= 0
        }
    }

public enum class Event {
        ON_CREATE,
        ON_START,
        ON_RESUME,
        ON_PAUSE,
        ON_STOP,
        ON_DESTROY,
        ON_ANY; 
        .......
      }

可以看到是由两个枚举类来实现的,按照Google官方文档的说法,我们可以可以将状态看作图中的节点,将事件看作这些节点之间的边(上图中)。一旦Lifecycle的状态由一个转变到另一个,就会触发它的Event事件,这个事件会被分发到观察者之中去执行响应的回调方法。

LifecycleOwner接口

LifecycleOwner的作用就是标记一个类具有生命周期,或者更具体地说,表明这个类可以由Lifecycle框架所管理,这个接口只有一个方法(成员变量),是用于获取具体的Lifecycle对象的:

kotlin 复制代码
public interface LifecycleOwner {
    /**
     * Returns the Lifecycle of the provider.
     *
     * @return The lifecycle of the provider.
     */
    public val lifecycle: Lifecycle
}

在Kotlin版本中这个类还有一个指向协程作用域的变量,可以在创建协程时使用:

kotlin 复制代码
public val LifecycleOwner.lifecycleScope: LifecycleCoroutineScope
    get() = lifecycle.coroutineScope

这个接口从各个类中(具体来说是Fragment或者Activity等组件)抽象出了生命周期,并将其提供给其他组件来使用。

Activity中的Lifecycle来源

Activity肯定是一个有生命周期的组件,并且我们也可以通过getLifecycle方法获取到具体的生命周期对象,我们可以点进去,发现这个方法返回的是一个ComponentActivity类的成员变量,这个ComponentActivity类是Activity的父类:

java 复制代码
	private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }

可以看到这个Activity中Lifecycle是由LifecycleRegistry实现的,一般情况下我们也是用这个类来实现Lifecycle的实体的。这个类为了防止内存泄漏是用弱引用来存储LifecycleOwner的(此处具体来说就是ComponentActivity):

kotlin 复制代码
private val lifecycleOwner: WeakReference<LifecycleOwner>

初次之外,其中还有几个成员变量我们先来提前介绍一下:

kotlin 复制代码
private var state: State = State.INITIALIZED //Lifecycle当前的State,初始化时默认是INITIALIZED 
private var observerMap = FastSafeIterableMap<LifecycleObserver, ObserverWithState>() //存储观察者的表,该表支持在迭代中修改
private var handlingEvent = false //标志位,判断当前Lifecycle是否正在处理事件

ReportFragment--用来追踪Activity生命周期变化

这里我们还是需要返回到ComponentActivity中去,Activity的Lifecycle状态是在哪里修改的呢?

kotlin 复制代码
    @CallSuper
    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        Lifecycle lifecycle = getLifecycle();
        if (lifecycle instanceof LifecycleRegistry) {
            ((LifecycleRegistry) lifecycle).setCurrentState(Lifecycle.State.CREATED);
        }
        super.onSaveInstanceState(outState);
        mSavedStateRegistryController.performSave(outState);
    }

可以看到此处方法中的第三行将当前Lifecycle的状态设置为了CREATED,具体是从INITIALIZED 转变过去的。不过以一般的角度思考,正常应该是在ComponentActivity中的各个生命周期回调中改变,对于Actvity来说,它将这个任务交给了一个特殊的Fragment--ReportFragment,这个Fragment是在onCreate中创建出来的:

java 复制代码
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        mSavedStateRegistryController.performRestore(savedInstanceState);
        mContextAwareHelper.dispatchOnContextAvailable(this);
        super.onCreate(savedInstanceState);
        ReportFragment.injectIfNeededIn(this); //注入ReportFragment
        if (BuildCompat.isAtLeastT()) {
            mOnBackPressedDispatcher.setOnBackInvokedDispatcher(
                    Api33Impl.getOnBackInvokedDispatcher(this)
            );
        }
        if (mContentLayoutId != 0) {
            setContentView(mContentLayoutId);
        }
    }

具体就是标注出来的ReportFragment.injectIfNeededIn(this),从命名可以看出来是一个注入方法,它将一个ReportFragment注入到了ComponentActivity之中里去了:

kotlin 复制代码
        @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()
            }
        }

这个方法首先会判断当前API版本是否大于29,如果大于就直接调用LifecycleCallbacks.registerIn(activity)方法进行注册,否则会通过Activity的FragmentManager来将ReportFragment添加进去。这个API判断不重要,反正最后做到的效果就是ComponentActivity之中有了一个用来追踪生命周期的ReportFragment了。

ReportFragment感知生命周期变化

由于是Fragment,其生命周期是由FragmentManager管理的,而这个FragmentManager又是Actvity的一部分,所以当Actvity的状态发生改变的时候会触发FragmentManager进行事件的分发,进而触发其管理下的Fragment的生命周期的变化。**总之我们记住一点,这个ReportFragment可以感知到Activity的生命周期变化。**所以,Lifecycle状态的变更应该是会在这个特殊的Fragment之中进行的,我们来看它的onActivityCreated方法:

kotlin 复制代码
    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        dispatchCreate(processListener)
        dispatch(Lifecycle.Event.ON_CREATE)
    }

    override fun onStart() {
        super.onStart()
        dispatchStart(processListener)
        dispatch(Lifecycle.Event.ON_START)
    }

    override fun onResume() {
        super.onResume()
        dispatchResume(processListener)
        dispatch(Lifecycle.Event.ON_RESUME)
    }

    override fun onPause() {
        super.onPause()
        dispatch(Lifecycle.Event.ON_PAUSE)
    }

可以看到不仅仅是onActivityCreated方法,它的其他生命周期的回调中也调用了dispatch方法,从名字就可以看出来这是一个用来分发生命周期事件的方法,马上进入到这个方法之中:

kotlin 复制代码
        @JvmStatic
        internal fun dispatch(activity: Activity, event: Lifecycle.Event) {
            if (activity is LifecycleRegistryOwner) {
                activity.lifecycle.handleLifecycleEvent(event)
                return
            }
            if (activity is LifecycleOwner) {
                val lifecycle = (activity as LifecycleOwner).lifecycle
                if (lifecycle is LifecycleRegistry) {
                    lifecycle.handleLifecycleEvent(event)
                }
            }
        }

可以看到主要是调用到了Activity内部的Lifecycle对象进行事件的处理。

Lifecycle处理生命周期事件

上面说到通过handleLifecycleEvent方法进行生命周期事件的处理,我们再来看这个方法:

kotlin 复制代码
    open fun handleLifecycleEvent(event: Event) {
        enforceMainThreadIfNeeded("handleLifecycleEvent")
        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()
        }
    }

这里可以看到,主要是触发了moveToState方法,其中还涉及到event.target的取值,我们先来看这个event.target:

kotlin 复制代码
        public val targetState: State
            get() {
                when (this) {
                    ON_CREATE, ON_STOP -> return State.CREATED
                    ON_START, ON_PAUSE -> return State.STARTED
                    ON_RESUME -> return State.RESUMED
                    ON_DESTROY -> return State.DESTROYED
                    ON_ANY -> {}
                }
                throw IllegalArgumentException("$this has no target state")
            }

这个方法也很好懂,根据传入的事件判断接下来Lifecycle的状态(State),如果忘了我们再来看一下那张图,可以发现完全对的上:

那么接下来的moveToState方法也很好懂了,就是将当前Lifecycle的状态转变到另一个状态,首先当目标状态和当前状态一致的话不会执行任何动作,接下来就直接返回。之后比较重要的部分就是sync方法了,在执行sync方法之前会将handingEvent标志位置为true,标志Lifecycle目前正在处理事件。至于这个sync方法,看名字也知道是一个用来同步内部状态的方法,具体同步的是什么呢?我们接下来继续看sync方法。

sync方法:

kotlin 复制代码
    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) { .//当当前Lifecycle还没有完成同步的话
            newEventOccurred = false //新事件发生标志位为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
    }

首先while的判断条件是当前Lifecycle是否已经完成了必要的同步,如果还没有完成的话接下来就要进行同步。之前的方法中我们已经获得了当前Lifecycle之后要转变的状态,但是如果我们继续回看上面那张图就会发现光有一个目标状态还不行,还要判断转变的方法,比如说CREATED状态和STARTED状态,如果是向后转变要触发的应该是ON_START事件,反之则应该是ON_STOP事件。这里的if (state < observerMap.eldest()!!.value.state)以及后边的那个if分支就是用来判断状态转变的方向的。这里会涉及到观察者的生命周期,这里我们先不管,**先知道这里判断出了状态转变的方向。**我们以forwardPass方法为例看其实现。

forwardPass方法:

kotlin 复制代码
    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()
            }
        }
    }

首先会获得整个Lifecycle的Observer集合的迭代器,并且在第二个while循环中会将状态低于当前State的观察者Observer,所谓状态低我们也可以看上面那幅图,越靠近左边是State的值越小。这里我们又要考虑到这个方法是将状态向后移的情况,所以之前观察者集合中的State显然是不可能比当前State大的,所以说只要考虑observer.state < state的情况就好了。

然后会通过Event.upFrom方法获得观察者所需要的事件然后发送给对应的观察者,这样观察者就会触发其回调了,具体是observer.dispatchEvent(lifecycleOwner, event)这一行,我们来看dispatchEvent方法,这是ObserverWithState类的方法:

kotlin 复制代码
    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的事件之后记录下的对应Lifecycle的State,可以说它记录的就是Lifecycle发生本次事件传递之前的状态。在其dispatchEvent方法之中最终会调用到lifecycleObserver方法,这个方法不用多说就是我们注册时传入的实现了观察者接口的方法。到这里就完成了整个Lifecycle生命感知和事件传递的过程,我们再用一幅图来总结一下:

LifecycleObserver接口

最后我们再来说明一下LifecycleObserver接口,具体来说这是一个标签接口,该标签的意义就是标记一个类可以用来观察Lifecycle。如果看过一些老旧的书的话,我们会发现之前这个Lifecycle的回调是用OnLifecycleEvent注解实现的,不过他现在已经被废弃了。

LifecycleObserver有两个具体子接口:DefaultLifecycleObserverLifecycleEventObserver,这两个都是可以使用的,不过一般情况下我们使用DefaultLifecycleObserver就可以了。这两个类之间也存在优先级的关系,DefaultLifecycleObserver的优先级是高于LifecycleEventObserver 的,这是什么意思呢?就是一个类可以即实现DefaultLifecycleObserver类,又实现LifecycleEventObserver,这种情况下DefaultLifecycleObserver的回调将先于LifecycleEventObserver发生。

最后我们也来附一张图:

相关推荐
众拾达人27 分钟前
Android自动化测试实战 Java篇 主流工具 框架 脚本
android·java·开发语言
吃着火锅x唱着歌1 小时前
PHP7内核剖析 学习笔记 第四章 内存管理(1)
android·笔记·学习
_Shirley3 小时前
鸿蒙设置app更新跳转华为市场
android·华为·kotlin·harmonyos·鸿蒙
9527华安3 小时前
FPGA多路MIPI转FPD-Link视频缩放拼接显示,基于IMX327+FPD953架构,提供2套工程源码和技术支持
fpga开发·架构·音视频
hedalei4 小时前
RK3576 Android14编译OTA包提示java.lang.UnsupportedClassVersionError问题
android·android14·rk3576
锋风Fengfeng4 小时前
安卓多渠道apk配置不同签名
android
枫_feng5 小时前
AOSP开发环境配置
android·安卓
叶羽西5 小时前
Android Studio打开一个外部的Android app程序
android·ide·android studio
qq_171538857 小时前
利用Spring Cloud Gateway Predicate优化微服务路由策略
android·javascript·微服务
Vincent(朱志强)8 小时前
设计模式详解(十二):单例模式——Singleton
android·单例模式·设计模式