JetPack-(3)-LifeCycle 生命周期组件

137 阅读7分钟

1 Lifecycle的作用是什么?

LifeCycle可以帮助开发者创建可感知生命周期的组件。这样组件能够在其内部管理自己的生命周期,从而降低模块间的耦合度,并降低内存泄漏发生的可能性。

2 为什么要引入LifeCycle:

例如我们经常需要在页面的onCreate()方法中对组件进行初始化,在onPause()方法中停止组件,在onDestroy()方法中对组件进行资源回收工作。这种工作非常繁琐且会让页面与组件之间的耦合度变高。但是这些工作又不得不做,因为这可能会引发内存泄漏。

       举个例子:当用户打开某个页面时,获取用户当前的地理位置。那我们通常就是在onCreate方法里面去进行注册,然后再onDestroy方法里面进行销毁。一般我们都是通过在BaseActivity中对所需要的组件进行初始化和销毁,然后让其他的Activity继承BaseActivity,这样可以减少很多不必要的代码。

1710310795555.jpg

        但是现在LifeCycle可能更好的解决这个问题。LifeCycle不只对Activity/Fragment有用,在Service和Application中也能够使用。所有具体生命周期的组件都能够使用LifeCycle.并且有了LifeCycle之后,在自定义组件内部便可以管理好其生命周期,不再需要担心组件的内存泄露等问题了,组件使用起来也更加方便和安全.

总结来说,LifeCycle的出现是为了解决系统组件的生命周期与普通组件之间的耦合性。

  • 系统组件指: Activity/Fragment Service和Application
  • 普通组件指:将代码按照功能或者作用封装成的组件

1710311228551(1).jpg

3.LifeCycle的原理

JetPack为我们提供了两个类:LifecycleOwner(被观察者) 和 LifecycleObserver(观察者),即通过观察者模式,实现对页面生命周期的监听在AndroidX里面ComponentActivity已经默认实现了LifecycleOwner接口,并且接口中只有一个getLifeCycle(LifecycleObserver observer)方法,LifecycleOwner正是通过该方法实现观察者模式的。 ComponentActivity已经替我们实现了被观察者应该实现的那一部分代码。当我们希望监听Activity的生命周期的时候,只需要实现观察者那一部分的代码,即让自定义组件实现LifecycleObserver接口即可。该接口没有接口方法

4 Lifecycle使用:

4.1 Lifecycle解耦Activity 与Fragment

4.1.1 解耦Activity

步骤:

  1. 首先编写一个类实现LifecycleObserver接口,然后对于那些需要在页面生命周期发生变化时得到通知的方法,在这些方法上使用@OnLifecycleEvent(Lifecycle.Event.On_....)注解进行标识。
  2. 创建实现LifecycleObserver接口的类,通过getLifecycle().addObserver()方法,将观察者与被观察者绑定起来即可。
  3. Fragment同样也默认实现了LifecycleOwner接口,因此Fragment与Activity使用方式一样

使用:

第一步,实现观察者

如果是想监听某个 Activity 的生命周期,需要我们做的就是自定义组件,实现 LifecycleObserver 接口即可,该接口没有接口方法,不需要任何具体的实现。

1710313109093.jpg

第二步 在MainActivity中对MyVideoPlayListener进行引用即可

1710313790001.jpg

4.1.1 解耦Fragment

在新版的SDK中,Fragment同样也默认实现了LifecycleOwner接口,因此,以上的例子同样适合于Fragment 这里就不再赘述。

4.2 使用LifecycleService解耦Service组件

为了方便对于Service生命周期的监听,LifeCycle提供了一个名为LifeCycleService的类,也实现了LifecycleOwner接口

1710315292244.jpg

4.2.1 第一步 添加相关依赖

dependencies {
	implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
}

4.2.2 第二步 创建一个类实现LifecycleObserver接口

创建一个类实现LifecycleObserver接口,使用@OnLifecycleEvent()注解对那些需要在Service生命周期发生变化时得到同步调用的方法进行标识

1710316261985.jpg

4.2.3 第三步 创建一个类继承LifecycleService

创建一个类继承LifecycleService,LifecycleService是Service的直接子类,所以使用起来和普通Service没有区别,然后创建一个无参构造器,初始化实现了LifecycleObserver接口的类。最后通过getLifecycle().addObserver()将观察者与被观察者绑定起来即可。

1710315623935.jpg

4.2.4 第四步 在页面中利用两个Button,控制Service的启动和停止,测试代码:

1710316011614.jpg

通过LogCat中的日志可以看到,随着Service生命周期的变化,MyServiceObserver中带有@OnLifecycleEvent注解的方法被自动调用

1710316225605.jpg 注意需要在清单文件中(manifest)注册MyService

 <application
  	   <service android:name=".lifecycle.MyService"/>
  </application>


4.3 使用ProcessLifecycleOwner监听应用程序的生命周期

4.3.1 创建一个类实现LifecycleObserver类

定义一个名为ApplicationObserver的类,让该类实现LifecycleObserver接口,以负责对应用程序生命周期的监听

package com.wzj.lifecycledemo;

import android.util.Log;

import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;

public class ApplicationObserver implements LifecycleObserver {
   //在应用程序的整个生命周期中只会被调用一次
   @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
   public  void onCreate(){
       Log.e("application","Application onCreate方法执行了");
   }


   //在应用程序在前台出现时被调用
   @OnLifecycleEvent(Lifecycle.Event.ON_START)
   public  void onStart(){
       Log.e("application","Application onStart方法执行了");
   }

   //在应用程序在前台出现时被调用
   @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
   public  void onResume(){
       Log.e("application","Application onResume方法执行了");
   }

   //在应用程序退出到后台时被调用
   @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
   public  void onPause(){
       Log.e("application","Application onPause方法执行了");
   }

   //在应用程序退出到后台时被调用
   @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
   public  void onStop(){
       Log.e("application","Application onStop方法执行了");
   }


   //永远不会被调用,系统不会分发调用ON_DESTROY事件
   @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
   public  void onDestroy(){
       Log.e("application","Application onDestroy方法执行了");
   }
}

4.3.2自定义Application 继承Application

ProcessLifecycleOwner的使用方式与Activity、Fragment和Service是类似的,其本质也是观察者模式。由于我们要观察的是整个应用程序,因此,需要在Application中进行相关代码的编写

1710316726451.jpg

4.3.3 结果展示

1710316760875.jpg

4.3.4 需要注意的是:

  1. ProcessLifecycleOwner是针对整个应用程序的监听,与Activity数量无关,无论有多少个Activity或Fragment,对ProcessLifecycleOwner来说是没有区别的。

  2. Lifecycle.Event.ON_CREATE只会被调用一次,而Lifecycle.Event.ON_DESTROY永远不会被调用。这也是因为ProcessLifecycleOwner监听的是整个应用程序的生命周期,而不是单个组件(如Activity/Fragment)的生命周期

  3. 应用程序从后台回到前台,或者应用程序被首次打开时,会依次调用Lifecycle.Event.ON_START和Lifecycle.Event.ON_RESUME。

  4. 应用程序从前台退到后台(用户按下Home键或任务菜单键),会依次调用Lifecycle.Event.ON_PAUSE和Lifecycle.Event.ON_STOP

4.4 LifeCycle的另外两种写法

4.4.1 DefaultLifecycleObserver

DefaultLifecycleObserver拥有宿主所有生命周期事件 DefaultLifecycleObserver 接口中有 6 个生命周期方法:

public interface DefaultLifecycleObserver extends FullLifecycleObserver {

    @Override
    default void onCreate(@NonNull LifecycleOwner owner) {
    }

    @Override
    default void onStart(@NonNull LifecycleOwner owner) {
    }

    @Override
    default void onResume(@NonNull LifecycleOwner owner) {
    }

    @Override
    default void onPause(@NonNull LifecycleOwner owner) {
    }

    @Override
    default void onStop(@NonNull LifecycleOwner owner) {
    }

    @Override
    default void onDestroy(@NonNull LifecycleOwner owner) {
    }
}

该接口继承自FullLifecycleObserver,由于权限问题,我们不能直接使用FullLifecycleObserver来拥有宿主的所有生命周期事件.

所以,我们需要通过实现DefaultLifecycleObserver接口,然后重写自己业务需要监听的生命周期方法。

public class MyVideoPlayListener implements DefaultLifecycleObserver {
    private static String TAG="MyVideoPlayListener";
    @Override
    public void onCreate(@NonNull LifecycleOwner owner) {
        DefaultLifecycleObserver.super.onCreate(owner);
        Log.d(TAG, "onCreate: ");
    }

    @Override
    public void onStart(@NonNull LifecycleOwner owner) {
        DefaultLifecycleObserver.super.onStart(owner);
        Log.d(TAG, "onStart: ");
    }

    @Override
    public void onResume(@NonNull LifecycleOwner owner) {
        DefaultLifecycleObserver.super.onResume(owner);
        Log.d(TAG, "onResume: ");
    }

    @Override
    public void onPause(@NonNull LifecycleOwner owner) {
        DefaultLifecycleObserver.super.onPause(owner);
        Log.d(TAG, "onPause: ");
    }

    @Override
    public void onStop(@NonNull LifecycleOwner owner) {
        DefaultLifecycleObserver.super.onStop(owner);
        Log.d(TAG, "onStop: ");
    }

    @Override
    public void onDestroy(@NonNull LifecycleOwner owner) {
        DefaultLifecycleObserver.super.onDestroy(owner);
        Log.d(TAG, "onDestroy: ");
    }
}

然后在Activity中:将观察者与被观察者绑定起来即可

MyVideoPlayListener myVideoPlayListener = new MyVideoPlayListener();
getLifecycle().addObserver(myVideoPlayListener);

效果展示:

1710317914596.jpg

4.4.2 LifecycleEventObserver

将宿主生命周期事件封装成Lifecycle.Event

public class MyVideoPlayListener implements LifecycleEventObserver {
    private static String TAG = "MyVideoPlayListener";

    @Override
    public void onStateChanged(@NonNull LifecycleOwner lifecycleOwner, @NonNull Lifecycle.Event event) {
        switch (event) {
            case ON_CREATE:
                Log.d(TAG, "onCreate(): ");
                break;
            case ON_START:
                Log.d(TAG, "onStart(): ");
                break;
            case ON_RESUME:
                Log.d(TAG, "onResume(): ");
                break;
            case ON_PAUSE:
                Log.d(TAG, "onPause(): ");
                break;
            case ON_STOP:
                Log.d(TAG, "onStop(): ");
                break;
            case ON_DESTROY:
                Log.d(TAG, "onDestroy(): ");
                break;
            default:
                break;
        }
    }
}

然后在Activity中:将观察者与被观察者绑定起来即可

MyVideoPlayListener myVideoPlayListener = new MyVideoPlayListener();
getLifecycle().addObserver(myVideoPlayListener);

效果展示:

1710318194577.jpg

4.4.3 对于这三种实现方式如何选择:

建议使用DefaultLifecycleObserver 和 LifecycleEventObserver的方式

  • Java8使用DefaultLifecycleObserver来实现Lifecycle,Java7使用注解的方式,如果一旦Java8称为Android的主流后,注解的方式会被弃用

  • 如果一个类同时实现了DefaultLifecycleObserver接口和LifecycleEventObserver接口,那么DefaultLifecycleObserver中的方法会先触发,然后才执行 LifecycleEventObserver 的 onStateChanged 方法。

  • 如果一个类实现了 DefaultLifecycleObserver 接口,同时使用了 @OnLifecycleEvent 注解,那么注解的方式会被自动忽略掉。

引用:

(blog.csdn.net/sinat_35109…)

(blog.csdn.net/qq_43404873…)

(hanshuliang.blog.csdn.net/article/det…)

LifeCycle组件原理 blog.csdn.net/sinat_35109…