美文网首页 Android知识进阶(遥远的重头开始)Android-Jetpack
Android 架构组件之 LifeCycle详解(转载+实践+

Android 架构组件之 LifeCycle详解(转载+实践+

作者: MonkeyLei | 来源:发表于2020-04-01 11:37 被阅读0次

    **已经融入: **MonkeyLei:Android_组件化MVVM组件化+LiveData+ViewModel+Repository

    有相关接口DefaultLifecycleObserver无法使用的可以参考androidx.lifecycle..DefaultLifecycleObserver not found ( 一般采用最新的方式,之前依赖了ViewModel的话,只需要像上面工程配置依赖下java8的就可以了。Lifecycle | Android 开发者 | Android Developers - 这是对应的依赖参考; arch已经逐渐抛弃了。。)另外官方建议不用注解,采用继承方式比较好!

    同时: androidx.lifecycle " lifecycle-common-java8 这是官方的最新的java8的common版本信息,供参考

    1、Lifecycle介绍

    lifecycle官方文档地址:
    https://developer.android.com/topic/libraries/architecture/lifecycle

    为什么要使用lifecycle?

    activity 和fragment 是有声明周期的,有时候,我们的很多操作需要写在声明周期的方法中,比如,下载,文件操作等,这样很多情况下回导致,我们在activity中的声明周期方法中写越来越多的代码,activity或者fragment 越来越臃肿,代码维护越来越困难。 使用lifecycle就可以很好的解决这类问题。
    lifecycle代码简洁,我们可以通过实现LifecycleObserver 接口,来监听声明周期,然后我们在activity和fragment中去注册监听。

    2、几个重要的类和接口

    • Lifecycle
      Lifecycle是一个持有组件生命周期状态(如Activity或Fragment)的信息的类,并允许其他对象观察此状态。
    • Event :从框架和Lifecycle类派发的生命周期事件。这些事件映射到活动和片段中的回调事件。
    • State :由Lifecycle对象跟踪的组件的当前状态。
    • LifecycleOwner (重要)Lifecycle持有者
    • 实现该接口的类持有生命周期(Lifecycle对象),该接口的生命周期(Lifecycle对象)的改变会被其注册的观察者LifecycleObserver观察到并触发其对应的事件。
    • LifecycleObserver(重要)Lifecycle观察者
    • 实现该接口的类,通过注解的方式,可以通过被LifecycleOwner类的addObserver(LifecycleObserver o)方法注册,被注册后,LifecycleObserver便可以观察到LifecycleOwner的生命周期事件。

    3、LifeCycle中两个重要的接口LifeCycleOwner和LifecycleObserver 的使用

    (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对象,来添加观察者监听。

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

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

    两种实现方式:

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

    Lifecycle.java文档中是建议使用第一种方式,因为文档中说明了,随着Java8成为主流,注解的方式会被弃用。DefaultLifecycleObserver是需要另外声明的java8 比如下面
    GenericLifecycleObserver,FullLifecycleObserver,DefaultLifecycleObserver 这三个接口都是直接或者间接继承的LifecycleObserver

    // 如果使用的是java 8要显示声明如下的
    def lifecycle_version = "1.1.1"
    implementation "android.arch.lifecycle:common-java8:$lifecycle_version"
    
    image

    3、开始使用Lifecycle

    我们写个测试代码,首先,我们要测试一下,到底LifecycleObserver到底能不能监听到声明周期的变化。并且实验下上图中的声明周期状态
    先写两个简单的Activity,FirstActivity 和SecondActivity, 单纯的一个跳转。

    public class FirstActivity extends AppCompatActivity {
    
        private Button firstBtn;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.first_activity_layout);
            initView();
            initListener();
        }
    
        private void initView() {
            firstBtn = findViewById(R.id.first_btn);
        }
    
        private void initListener() {
            firstBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
                    startActivity(intent);
                }
            });
        }
    }
    

    接下来,我们要做的是要写一个需要拥有声明周期的类,正常我们自定义控件啊,或者做其他逻辑的类,是没有声明周期的,现在有了LifecycleObserver,我们可以让一个普通的类拥有感知声明周期变化的能力。比如,现在自定义一个,MyObserver类。

    public class MyObserver implements DefaultLifecycleObserver{
       private static final String TAG = "MyListener";
    
        @Override
        public void onCreate(@NonNull LifecycleOwner owner) {
            Log.d(TAG,"onCreate()");
            Log.d(TAG,"当前生命周期状态="+lifecycle.getCurrentState().name());
        }
    
        @Override
        public void onStart(@NonNull LifecycleOwner owner) {
            Log.d(TAG,"onStart()");
            Log.d(TAG,"当前生命周期状态="+lifecycle.getCurrentState().name());
        }
    
        @Override
        public void onResume(@NonNull LifecycleOwner owner) {
            Log.d(TAG,"onResume()");
            Log.d(TAG,"当前生命周期状态="+lifecycle.getCurrentState().name());
    
        }
    
        @Override
        public void onPause(@NonNull LifecycleOwner owner) {
            Log.d(TAG,"onPause()");
            Log.d(TAG,"当前生命周期状态="+lifecycle.getCurrentState().name());
        }
    
        @Override
        public void onStop(@NonNull LifecycleOwner owner) {
            Log.d(TAG,"onStop()");
            Log.d(TAG,"当前生命周期状态="+lifecycle.getCurrentState().name());
        }
    
        @Override
        public void onDestroy(@NonNull LifecycleOwner owner) {
            Log.d(TAG,"onDestroy() ");
            Log.d(TAG,"当前生命周期状态="+lifecycle.getCurrentState().name());
        }
    
    }
    

    我们采取的是,直接继承DefaultLifecycleObserver接口,来实现它所有的方法。我们在里面做了log,来查看,是否这个类,收到了activity声明周期的变化。
    然后,要做的就是注册监听
    在Activity 的OnCreate方法中,调用getLifecycle();

    public class FirstActivity extends AppCompatActivity {
    
        private Button firstBtn;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.first_activity_layout);
            initView();
            initListener();
            //添加了这一行代码
            getLifecycle().addObserver(new MyObserver());
        }
    
        private void initView() {
            firstBtn = findViewById(R.id.first_btn);
        }
    
        private void initListener() {
            firstBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
                    startActivity(intent);
                }
            });
        }
    }
    

    可以看到,api26,.1以后,Activity中可以直接 getLifecycle().addObserver(new MyObserver()); 这样,就已经注册了声明周期观察者的监听。运行查看log
    启动FirstActivity后,MyObserver类已经监听到了Activity的声明周期方法
    并且,和图中表示一致,各个声明周期方法对应相应的节点。一定要清楚,后面会用到。比如,onResume()方法执行后,Activity处于RESUME状态,我们可以通过判断这个状态来做一些事情

    image

    点击跳转到SecondActivity

    image

    可以看到,FirstActivity声明周期走了onPause onStop,MyObserver也成功监听到了,继续返回FirstActivity

    image

    最后,点击返回键,退出FirstActivity,

    image

    通过这个简单的小例子,我们看到了 我们的类,只要实现了 LifecycleObserver接口,然后,在Activity 或者Fragment中 通过getLifecycle().addObserver()方法,把这个类的对象传入,就可以实现声明周期的感应监听。

    当然,我们可以再初始化这个类的时候,把Lifecycle对象传入,那我们自定义的类就可以自己去管理声明周期,而不依赖activity或者fragment。 这样,activity在使用此类的时候就不必关系声明周期的问题,因为,在这个类里面我们已经处理了。比如: 给MyObserver类 添加一个构造方法,传入一个Lifecycle对象。

    要注意的是:
    生命周期状态为RESUMED时表示,当前activity 是在前台,并且可交互也就是onResume()执行后

    生命周期状态为STARTED时,表示当前activity处于可见但是不可交互,也就是onStart()方法刚执行完或者onPause()方法刚执行完的状态

    生命周期状态为CREATED,表示onCreate()方法刚刚执行完或者onStop()方法刚刚执行完,也就是当前activity不在前台,但是也没有处于销毁状态。

    生命周期状态为DESTORYED,表示当前Activity还不存在,没有被创建或者已经销毁,我们通常考虑比较多的就是,onDestory()方法执行后,当前Activity已经销毁。

    所以,如果我们要保证在Activity或者Fragment的有效生命周期内进行的操作,必须判断,当前lifecycle的状态是否至少是CREATED状态,避免Activity或者fragment销毁了以后,回调或者网络请求才回来,此时做一些操作会导致异常。

    添加以下代码,就是我们把lifecycle对象传给观察者,让它自己去判断回调后的代码,保证至少是CREATED状态

    private Lifecycle lifecycle;
       public MyObserver(Lifecycle lifecycle) {
            this.lifecycle = lifecycle;
        }
    //然后再相应的回调方法中使用下面代码判断,保证数据回调回来,当前activity是存在的
        if (lifecycle.getCurrentState().isAtLeast(CREATED)) {
                //这里只是示例,不一定是CREATED
        }
    

    这里用到了Lifecycle类的方法,下面我们看一下Lifecycle的源码

    public abstract class Lifecycle {
        @MainThread  //添加将在LifecycleOwner更改状态时通知的LifecycleObserver。
        public abstract void addObserver(@NonNull LifecycleObserver observer);
    
        @MainThread //从观察者列表中删除给定的观察者。
        public abstract void removeObserver(@NonNull LifecycleObserver observer);
    
        @MainThread //返回生命周期的当前状态。
        public abstract State getCurrentState();
    
        @SuppressWarnings("WeakerAccess")
        public enum Event {
    
            ON_CREATE,//用于onCreate事件的常量LifecycleOwner。
    
            ON_START,
    
            ON_RESUME,
    
            ON_PAUSE,
    
            ON_STOP,
    
            ON_DESTROY,
    
            ON_ANY //一个Event可以用来匹配所有事件的常数。 
        }
    
        @SuppressWarnings("WeakerAccess")
        public enum State {
    
            DESTROYED,
            INITIALIZED, //LifecycleOwner的初始化状态。 
            CREATED, 
            STARTED,
            RESUMED;
                    //比较此状态是否大于或等于给定值state。
            public boolean isAtLeast(@NonNull State state) {
                return compareTo(state) >= 0;
            }
        }
    }
    
    /**
     * Marks a class as a LifecycleObserver. It does not have any methods, instead, relies on
     * {@link OnLifecycleEvent} annotated methods.
     * <p>
     * @see Lifecycle Lifecycle - for samples and usage patterns.
     */
    @SuppressWarnings("WeakerAccess")
    public interface LifecycleObserver {
    
    }
    

    就是一个抽象类,注释已经很详细了,应该不用解释了

    最后借用下官网的-生命周期感知组件的最佳实战

    1. 尽可能保持您的UI控制器(活动和片段)尽可能精简。他们不应该试图获取他们自己的数据;相反,使用ViewModel来做到这一点,并观察一个LiveData对象来反映更改回视图。
    2. 尝试编写数据驱动的用户界面,其中您的用户界面控制器的职责是在数据更改时更新视图,或将用户操作通知给ViewModel。
    3. 把你的数据逻辑放在ViewModel类中。ViewModel应作为您的UI控制器和其他应用程序之间的连接器。但要小心,ViewModel不负责提取数据(例如,来自网络)。相反,ViewModel应调用相应的组件来获取数据,然后将结果提供给UI控制器。
    4. 使用dataBinding在视图和UI控制器之间保持干净的界面。这使您可以使您的视图更具说明性,并最大限度地减少需要在活动和片段中编写的更新代码。

    如果你喜欢用Java编程语言来做到这一点,可以使用像Butter Knife这样的库来避免样板代码并且有更好的抽象。

    1. 如果您的UI很复杂,请考虑创建一个演示者类(presenter)来处理UI修改。这可能是一项艰巨的任务,但它可以使您的UI组件更易于测试。
    2. 避免在ViewModel中引用View或Activity上下文。

    如果ViewModel超出活动(在配置更改的情况下),则活动会泄漏并且垃圾收集器无法正确处理。

    借用下https://blog.csdn.net/zhuzp_b... 作者的两张图,更清晰,对于相信信息,可到作者博客去查看相关讲解

    image image

    来自: https://segmentfault.com/a/1190000015117758

    相关文章

      网友评论

        本文标题:Android 架构组件之 LifeCycle详解(转载+实践+

        本文链接:https://www.haomeiwen.com/subject/wlpouhtx.html