Android :安卓第一行代码学习笔记之 解析LifeCycle 的简单理解和使用

Posted JMW1407

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android :安卓第一行代码学习笔记之 解析LifeCycle 的简单理解和使用相关的知识,希望对你有一定的参考价值。

LifeCycles

1、Lifecycles 简介

Lifecycles 即生命周期,属于 Jetpack 架构组件之一的 Lifecycles 组件是可以为其它组件提供生命周期感知能力的一个组件,而具备了生命周期感知能力的组件就叫生命周期感知组件

那么什么是生命周期感知能力呢?

我们知道四大基础组件有生命周期,能感知这些生命周期的组件就具备了生命周期感知能力,所以我认为以前我们使用的 MVP 模式中的 Presenter 如果它通过接口等方式间接获得了 Activity 的生命周期,它也算是一个生命周期感知组件,但是这种获取生命周期的方式和 Lifecycles 比起来还是太 low 了,我们接着对比传统生命周期感知方式,聊一聊为什么使用 Lifecycles 组件。

2、为什么需要 Lifecycles 组件 ?

我们知道,一个 android App 之所以能够完成一系列复杂任务,都是基于各个基础组件之间的密切配合,我们熟知的四大组件(Activity、Service、Broadcast、Content Provider)是有生命周期的,并且 Android 的操作系统层或者 FrameWork 框架层会为其提供相应的回调,以便程序在不同的状态下做相对正确的事;

而普通的组件或者我们自己开发的一些组件就没有这个待遇了,我们通常需要在合适的时候,手动将这些第三方组件的状态控制方法,诸如启动/关闭/注册/拆除等,添加到具备生命周期的组件的回调中去才能使它们正确工作。

然后,随着时间推移版本迭代,引用的第三方组件越来越多,你的代码逐渐变成了这样

override fun onStart() 
    a.init()
    b.start()
    c.initialize()
    ...

...
override fun onStop()
    if(a!=null) a.remove()
    if(b!=null&&b.c!=null) 
        b.c.tearDown()
        b.stop()
     
    c.stop()
    ...

你可能会在 Presenter 中完成这一系列操作,但这其实没有解决根本问题:随着第三方组件越来越多的引入,你的 Presenter 也越来越难以维护和测试。而且还可能出现内存泄露的情况

override fun onStart() 
        Util.checkUserStatus  result ->
        // 此回调可能在 onStop 之后被调用
                if(result)
                b.start()
            
                             

...
override fun onStop()
        b.stop()

2.1、自定义方法举例

也许有点抽象,举个例子说明一下,比如有个需求,需要在一个界面比较频繁更新地理位置信息。当Activity走了onstop之后,你应该也要暂停更新地理位置,或者当Activity走destroy后,你要释放一些资源。下面用一些代码实例解析一下:

class MyLocationListener 
    public MyLocationListener(Context context, Callback callback) 					  
    
        // ...
    

    void start() 
        // 开始连接位置服务
    

    void stop() 
        // 停止连接位置服务
    
    
    void destroy()
        //释放资源
    


class MyActivity extends AppCompatActivity 
    private MyLocationListener myLocationListener;

    @Override
    public void onCreate(...) 
        myLocationListener = new MyLocationListener(this, new Callback()
            //回调更新UI
        );
    

    @Override
    public void onStart() 
        super.onStart();
        myLocationListener.start();
        //绑定actiivty的onStart周期函数
    

    @Override
    public void onStop() 
        super.onStop();
        myLocationListener.stop();
        //绑定actiivty的onStop周期函数
    
    
    @Override
    public void onDestroy() 
        super.onDestroy();
        myLocationListener.destroy();
        //绑定actiivty的onDestroy周期函数
    

随着第三方组件越来越多的引入,越来越难以维护和测试

3、 Lifecycles 组件 的使用

  • 1、实现LifecycleObserver接口
  • 2、LifeCycleaddObserver方法添加观察者
  • 3、通过@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)注解方式给方法加上注解,就实现了生命周期的调用
class MyLocationListener implements LifecycleObserver
    public MyLocationListener(Context context, Callback callback) 
        // ...
    

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    void start() 
        // 开始连接位置服务
    

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    void stop() 
        // 停止连接位置服务
    

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    void destroy()
        //释放资源
    


class MyActivity extends AppCompatActivity 
    private MyLocationListener myLocationListener;

    @Override
    public void onCreate(...) 
        myLocationListener = new MyLocationListener(this, new Callback()
            //回调更新UI
        );
        getLifecycle().addObserver(myLocationListener);
    
  

有关生命周期管理 Google说了要在ViewModel中处理数据逻辑 但不包括网络请求,尽量不要传递Activity的上下文和View的上下文避免内存泄漏,尽量不要再Activity或者Fragment中处理数据和逻辑,保持干净。当之后学完ViewModel和LiveData 还有DataBinding之后,就会发现,UI显示的处理和异常的处理真的方便。

4、 Lifecycles 组件 原理


Java 大白话讲解设计模式之 – UML类图

看下FragmentLifecycleOwnerLifecycleObserverLifecycle之间的类关系图。

  • Lifecycle组件成员Lifecycle被定义成了抽象类,LifecycleOwnerLifecycleObserver被定义成了接口;
  • Fragment实现了LifecycleOwner接口,该只有一个返回Lifecycle对象的方法getLifecyle()
  • FragmentgetLifecycle()方法返回的是继承了抽象类Lifecycle的LifecycleRegistry
  • LifecycleRegistry中定义嵌套类ObserverWithState,该类持有GenericLifecycleObserver对象,而GenericLifecycleObserver是继承了LifecycleObserver的接口。
  • Lifecycle:Lifecycle是一个持有组件生命周期状态(如Activity或Fragment)的信息的类,并允许其他对象观察此状态。
  • Event :从框架和Lifecycle类派发的生命周期事件。这些事件映射到活动和片段中的回调事件
  • State :由Lifecycle对象跟踪的组件的当前状态。

4.1、LifeCycle中两个重要的接口

LifecycleOwner (重要)Lifecycle持有者

  • 实现该接口的类持有生命周期(Lifecycle对象),该接口的生命周期(Lifecycle对象)的改变会被其注册的观察者LifecycleObserver观察到并触发其对应的事件。

LifecycleObserver(重要)Lifecycle观察者

  • 实现该接口的类,通过注解的方式,可以通过LifecycleOwneraddObserver(LifecycleObserver o)方法注册,被注册后,LifecycleObserver便可以观察到LifecycleOwner的生命周期事件。

4.1.1、LifecycleOwner(生命周期持有者接口)

官网介绍:LifecycleOwner是一个单一的方法接口,表示该类有一个Lifecycle。它有一个方法,getLifecycle()这个方法 必须由这个类来实现。如果您试图管理整个应用程序进程的生命周期,请参阅 ProcessLifecycleOwner。该接口从各个类(如Fragment和AppCompatActivity)抽象生命周期的所有权,并允许编写与它们一起工作的组件。

  • 任何自定义应用程序类都可以实现LifecycleOwner接口
  • 实现LifecycleObserver的组件与实现LifecycleOwner的组件无缝协作,因为所有者可以提供生命周期,观察者可以注册以观看

简单来说,LifecycleOwner就是一个接口,谁继承了它,就持有了lifecycle对象。然后就可以调用getLifecycle()方法获取继承了抽象类Lifecycle的LifecycleRegistry,然后调用 addObserver(@NonNull LifecycleObserver observer) 方法来注册监听。

这样,该接口的生命周期(Lifecycle对象)的改变会被其注册的观察者LifecycleObserver观察到并触发其对应的事件。

注意:

Support Library 26.1.0 及其以后的版本,Activity 和Fragment 已经实现了LifecycleOwner 接口,所以,我们可以直接在Activity 和Fragment中使用getLifecycle()方法来获取lifecycle对象,来添加观察者监听。

4.1.2、LifecycleObserver(生命周期观察者接口)

LifecycleObserver 是一个观察者接口,实现了它,可以通过注解或者继承的方式,来管理声明周期的监听。只要在持有lifecycle的类中注册了它,当声明周期发生变化时,它就能收到,进行我们自定义的操作。
两种实现方式:

  • 实现DefultLifecyceObserver接口,然后重写里面生命周期方法;
  • 直接实现LifecycleObserver接口,然后通过注解的方式来接收生命周期的变化;

4.2、时序图

对于Fragment、Lifecycle、LifecycleOwner、LifecycleObserver的关系有了一定了解后,可以看一个更直观的图,也就是下面的时序图:

  • 我们在Fragment(AppCompatActivity也一样)中调用getLifecycle()方法得到LifecycleRegistry对象,然后调用addObserver()方法并将实现了LifecycleObserver接口的对象作为参数传进去。这样一个过程就完成了注册监听的过程。
  • 后续就是Fragment生命周期变化时,通知LifecycleObserver的过程:
    • FragmentperformXXX()、onXXX()方法;
    • LifecycleRegistryhandleLifecycleEvent()方法;LifecycleObserveronXXX()方法。
  • Fragment中performCreate()、performStart()、performResume()会先调用自身的onXXX()方法,然后再调用LifecycleRegistry的handleLifecycleEvent()方法;
  • 而在performPause()、performStop()、performDestroy()中会先LifecycleRegistryhandleLifecycleEvent()方法,然后调用自身的onXXX()方法。

比如上面的例子中,打印出来的结果也确实符合我们的分析,打印结果如下:

12-01 14:12:59.250 1398-1398/com.shymanzhu.architecture D/MainActivity: onCreate: 
12-01 14:12:59.342 1398-1398/com.shymanzhu.architecture D/MainPresenter: onCreate: 
12-01 14:12:59.345 1398-1398/com.shymanzhu.architecture D/MainActivity: onStart: 
12-01 14:12:59.345 1398-1398/com.shymanzhu.architecture D/MainPresenter: onStart: 
12-01 14:12:59.346 1398-1398/com.shymanzhu.architecture D/MainActivity: onResume: 
12-01 14:12:59.346 1398-1398/com.shymanzhu.architecture D/MainPresenter: onResume: 
12-01 14:12:59.601 1398-1412/com.shymanzhu.architecture D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
12-01 14:12:59.609 1398-1398/com.shymanzhu.architecture I/imx6.gralloc: open gpu gralloc module!
12-01 14:12:59.847 1398-1412/com.shymanzhu.architecture I/OpenGLRenderer: Initialized EGL, version 1.4
12-01 14:13:27.348 1398-1398/com.shymanzhu.architecture D/MainPresenter: onPause: 
12-01 14:13:27.349 1398-1398/com.shymanzhu.architecture D/MainActivity: onPause: 
12-01 14:13:28.265 1398-1398/com.shymanzhu.architecture D/MainPresenter: onStop: 
12-01 14:13:28.266 1398-1398/com.shymanzhu.architecture D/MainActivity: onStop: 
12-01 14:13:28.267 1398-1398/com.shymanzhu.architecture D/MainPresenter: onDestroy: 
12-01 14:13:28.267 1398-1398/com.shymanzhu.architecture D/MainActivity: onDestroy: 

其实这个Lifecycle组件是设计模式中观察者模式的例子

参考

1、Jetpack系列学习笔记整理一 之LifeCycles
2、Android Jetpack架构组件之 Lifecycles(使用篇)
3、Android Jetpack组件之Lifecycles库详解
4、Android Jetpack - Lifecycles
5、Android 架构组件(一)——Lifecycle
6、Android官方架构组件:Lifecycle详解&原理分析

以上是关于Android :安卓第一行代码学习笔记之 解析LifeCycle 的简单理解和使用的主要内容,如果未能解决你的问题,请参考以下文章

Android :第一行安卓代码学习笔记之 全局获取 Context

Android :安卓第一行代码学习笔记之 material design简单理解和使用

Android :安卓第一行代码学习笔记之 ViewModel组件的简单理解和使用

Android:安卓学习笔记之MVP模式的简单理解和使用

Android:安卓学习笔记之MVP模式的简单理解和使用

Android:安卓学习笔记之MVP模式的简单理解和使用