欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android架构之LifeCycle组件

程序员文章站 2022-06-07 18:21:39
...

LifeCycle的简介

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

为什么要引入LifeCycle

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

假设有这样一个常见的需求:在用户打开某个页面时,获取用户当前的地理位置。面对该需求,我们通常会这样写代码。


class MainActivity extends AppCompatActivity {	
    public void onCreate(...) {
        //初始化位置管理器
        iniLocationManager();
    }

	public void onResume(){
		//开始获取用户的地理位置
		startGetLocation();
	}
	
    public void onPause() {
        //停止获取用户的地理位置
        stopGetLocation();   	
    }
    
    public void onDestroy() {
        //销毁位置管理器
        delGetLocation();   	
    }
}

每次都是在onCreate方法里面去进行注册,然后再onDestroy方法进行销毁,这样的代码毫无意义。 当前我们写一个BaseActivity对所需要的组件进行初始化和销毁,然后使其它的Activity继承自BaseActivity, 可以减少很多不必要的代码。

但是还有没有更好的办法呢? 当然是有的,那就是LifeCycle可以解决这个问题,LifeCycle不只对Activity/Fragment有用,在Service和Application中也能大显身手.接下来让我们来看看LifeCycle是如何解决的?

LifeCyCle的原理

Jetpack为我们提供了两个类: LifecycleOwner(被观察者)和LifecycleObserver(观察者). 即通过观察者模式,实现对页面生命周期的监听

可以通过查看SupportActivity的源码,Activity已经默认实现了LifecycleOwner接口,并且接口中只有一个getLifeCycle(LifecycleObserver observer)方法,LifecycleOwner正是通过该方法实现观察者模式的。源码示例如下
Android架构之LifeCycle组件
从以上源码可知,SupporyActiviry已经替我们实现了被观察者应该实现的那一部分代码。当我们希望监听Activity的生命周期时,只需要实现观察者那一部分的代码,即让自定义组件实现LifecycleObserver接口即可。该接口没有接口方法。

LifeCycle基本使用

  1. 编写一个名为MyLocationListener的类。该类就是我们自定义组件,我们需要让组件实现LifecycleObserver接口,与获取地理位置相关的代码再该类中完成
  2. 对于组件中那些需要再页面生命周期发送变化时得到通知的方法,我们需要在这些方法上使用@OnLifecycleEvent(Lifecycle.Event.ON_xxx)注解进行标识。这样,当页面生命周期发生变化时,这些被注解标识过的方法会被自动调用。

MyLocationListener 代码如下

public class MyLocationListener  implements LifecycleObserver {
    public MyLocationListener(Activity context, OnLocationChangeListener listener) {

        //初始化操作
        iniLocationManager();
    }

    private void iniLocationManager() {
    }

    //当Activity执行onResume()方法时,该方法会被自动调用
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    private  void startGetLocation(){
        Log.e("true","onResume"+"被调用了");
    }

    //当Activity执行onPause()方法时,该方法会被自动调用
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    private  void stopGetLocation(){
        Log.e("true","onPause"+"被调用了");
    }

    //当Activity执行onDestroy()方法时,该方法会被自动调用
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    private  void delGetLocation(){
        Log.e("true","onDestroy"+"被调用了");
    }
    //当地理位置发送改变时,通过该接口通知调用者
    public  interface  OnLocationChangeListener{
        void  onChanged(double latitude,double longitude);
    }
}

主MainActivity
在MainActivity中,只需要引用MyLocationListener即可,不用再关心Activity生命周期变化对该组件所带来的影响。生命周期的管理完全交给MyLocationListener内部自行处理。在Activity中要做的只是通过getLifecycle().addObserver()方法,将观察者与被观察者绑定起来,代码如下:

public class MainActivity extends AppCompatActivity {

    private  MyLocationListener myLocationListener;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        myLocationListener = new MyLocationListener(this, new MyLocationListener.OnLocationChangeListener() {
            @Override
            public void onChanged(double latitude, double longitude) {
                //展示收到的位置信息
            }
        });

        //将观察者与被观察者绑定
        getLifecycle().addObserver(myLocationListener);
    }
}

运行结果如下:
Android架构之LifeCycle组件
是不是很简单呢? LifeCycle完美解决了组件对页面生命周期的依赖问题。

除Activity之外,在新版本的SDK中,Fragment同样也默认实现了LifecycleOwner接口。因此,以上案例同样适用于Fragment。Fragment的源码如下所示。
Android架构之LifeCycle组件

LifeCycIeService基本介绍

众所周知,拥有生命周期概念的组件除了Activity和Fragment,还有一个非常重要的组件是Service,为了便于对Service生命周期的监听,Android提供了一个名为 LifecycleService的类,也实现了LifecycleOwner接口.

LifecycleService的源码如下所示

Android架构之LifeCycle组件

LifecycleService的使用

1.首先,在app的build.gradle文件中添加相关依赖

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

2.创建一个名为MyService的类,继承LifecycleService.由于LifecycleService是Service的直接子类,所以使用起来与普通Service没有差别

public class MyService extends LifecycleService {
        private  MyServiceObserver myServiceObserver;

    public MyService( ) {
        myServiceObserver = new MyServiceObserver();
        //将观察者与被观察者绑定
        getLifecycle().addObserver(myServiceObserver);
    }
}

3.创建MyServiceObserver类,该类实现LifecycleObserver接口,使用@OnLifecycleEvent注解对那些你希望能够在Service生命周期发生变化时得到同步调用的方法进行标识。

public class MyServiceObserver implements LifecycleObserver {

    //当Service的onCreate()方法被调用时,该方法会被调用
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    private  void startGetLocation(){
        Log.e("service","Service中的oncreate方法执行了");
    }

    //当Service的onDestroy()方法被调用时,该方法会被调用
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    private  void stopGetLocation(){
        Log.e("service","Service中的onDestroy方法执行了");
    }
}

4.在页面中利用两个Button,控制Service的 启动和停止,测试我们的代码

 Button startBtn = findViewById(R.id.startService);
        Button stopBtn = findViewById(R.id.stopService);

        startBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //启动服务
                Intent intent = new Intent(MainActivity.this, MyService.class);
                startService(intent);

            }
        });
        stopBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //停止服务
                Intent intent = new Intent(MainActivity.this, MyService.class);
                stopService(intent);
            }
        });

5.通过LogCat中的日志可以看到,随着Service生命周期的变化,MyServiceObserver中带有@OnLifecycleEvent注解的方法被自动调用.
Android架构之LifeCycle组件
6.千万别忘记了,需要在清单文件中(manifest)注册MyService

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

通过以上示例可以看出,当Service的生命周期发生变化时,不再需要主动对组件进行通知,组件能够在其内部自行管理好生命周期所带来的变化。LifecycleService很好地实现了组件与Service之间的解耦。

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

ProcessLifecycleOwner存在的意义
具有生命周期的系统组件除Activity、Fragment、Service外,还有Application。很多时候,我们会遇到这样的需求:我们想知道应用程序当前处在前台还是后台,或者当应用程序从后台回到前台时,我们能够得到通知。LifeCycle提供了一个名为ProcessLifecycleOwner的类,以方便我们知道整个应用程序的生命周期情况。

ProcessLifecycleOwner的具体使用

1.首先,在app的build.gradle文件中添加相关依赖

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

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

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        ProcessLifecycleOwner.get().getLifecycle()
                .addObserver(new ApplicationObserver());
    }
}

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

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方法执行了");
    }
}

运行如下
Android架构之LifeCycle组件
通过以上示例可以看出,有了ProcessLifecycleOwner,我们可以很轻松地获取应用程序何时退到后台,何时进入前台,进而执行一些业务操作。使用起来非常简单,并且不会给项目增加任何的耦合度, 但有以下几点需要注意:

  1. ProcessLifecycleOwner是针对整个应用程序的监听,与Activity数量无关,你有一个Activity或多个Activity,对ProcessLifecycleOwner来说是没有区别的。
  2. Lifecycle.Event.ON_CREATE只会被调用一次,而Lifecycle.Event.ON_DESTROY永远不会被调用。
  3. 当应用程序从后台回到前台,或者应用程序被首次打开时,会依次调用Lifecycle.Event.ON_START和Lifecycle.Event.ON_RESUME。
  4. 当应用程序从前台退到后台(用户按下Home键或任务菜单键),会依次调用Lifecycle.Event.ON_PAUSE和Lifecycle.Event.ON_STOP

自定义 LifecycleOwner

Support Library 26.1.0 及更高版本中的 Fragment 和 Activity 已实现 LifecycleOwner 接口。
Support Library 26.1.0以下可以自定义LifecleOwner;
Support Library 26.1.0 及更高版本自定义LifecycleOwner会报错,亲测。
这里就拿Activity来举例吧,当我们想自定义LifecycleOwner,我们可以使用LifecycleRegistry类,但需要将事件转发到该类。

什么叫将事件转发到该类呢?

  1. 如果是自定义的LifecycleOwner,想要实现对某个生命周期进行监听的话,需要使用lifecycleRegistry.markState(Lifecycle.State.xxxx);加入到监听队伍中.
  2. 比如说,我想对Activity中的onStart()方法进行监听,那么就需要将onStart()方法加入到监听队伍中, lifecycleRegistry.markState(Lifecycle.State.STARTED);
  3. 上面不是已经说明,LifecycleOwner必须需要实现一个getLifecycle()方法,改方法需要返回一个Lifecycle类型的值,也就是我们创建的lifecycleRegistry

具体代码如下

public class MainActivity extends AppCompatActivity  implements LifecycleOwner {

    private MyLocationListener myLocationListener;
    private LifecycleRegistry lifecycleRegistry;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lifecycleRegistry = new LifecycleRegistry(this);
        lifecycleRegistry.markState(Lifecycle.State.CREATED);

        myLocationListener = new MyLocationListener(this, new MyLocationListener.OnLocationChangeListener() {
            @Override
            public void onChanged(double latitude, double longitude) {
                //展示收到的位置信息
            }
        });
				

        //将观察者与被观察者绑定
        getLifecycle().addObserver(myLocationListener);
    }
    
	@Override
    protected void onResume() {
        super.onResume();
        lifecycleRegistry.markState(Lifecycle.State.RESUMED);
    }    
    @NonNull
    @Override
    public Lifecycle getLifecycle() {
        return lifecycleRegistry;
    }

MyLocationListener类上面有这里就不在给出了.

总结

所有具体生命周期的组件都能够使用LifeCycle.并且有了LifeCycle之后,在自定义组件内部便可以管理好其生命周期,不再需要担心组件的内层泄露等问题了,组件使用起来也更加方便和安全.

相关标签: Android Jetpack