Android架构之LifeCycle组件

Jetpack组件系列文章
Android架构之LifeCycle组件
Android架构之Navigation组件(一)
Android架构之Navigation组件(二)
Android架构之Navigation组件(三)
Android架构之Navigation组件(四)
Android架构之ViewModel组件
Android架构之LiveData组件
Android架构之Room组件(一)
Android架构之Room组件(二)
Android架构之WorkManager组件
Android架构之DataBinding(一)
Android架构之DataBinding(二)
Android架构之Paging组件(一)
Android架构之Paging组件(二)
Jetpack与MVVM架构

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正是通过该方法实现观察者模式的。源码示例如下
在这里插入图片描述
从以上源码可知,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);
    }
}

运行结果如下:
在这里插入图片描述
是不是很简单呢? LifeCycle完美解决了组件对页面生命周期的依赖问题。

除Activity之外,在新版本的SDK中,Fragment同样也默认实现了LifecycleOwner接口。因此,以上案例同样适用于Fragment。Fragment的源码如下所示。
在这里插入图片描述

LifeCycIeService基本介绍

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

LifecycleService的源码如下所示

在这里插入图片描述

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注解的方法被自动调用.
在这里插入图片描述
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方法执行了");
    }
}

运行如下
在这里插入图片描述
通过以上示例可以看出,有了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之后,在自定义组件内部便可以管理好其生命周期,不再需要担心组件的内层泄露等问题了,组件使用起来也更加方便和安全.

  • 8
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 《Jetpack架构组件从入门到精通》.pdf 是一本介绍Android Jetpack架构组件的书籍。Jetpack是Google官方提供的一套组件库,旨在帮助开发者更轻松地构建高质量的Android应用程序。 这本书从入门到精通地介绍了Jetpack架构组件的各个方面。首先,它详细解释了Jetpack的基本概念和使用方法。读者可以学习到Jetpack的核心组件,如ViewModel、LiveData、Room和Navigation等,以及它们在构建Android应用时的作用。 此外,这本书还介绍了Jetpack架构组件的一些高级技术和最佳实践。读者可以学习到如何使用WorkManager实现后台任务,如何使用DataBinding进行数据绑定,以及如何使用Paging构建分页列表等。 除了介绍Jetpack架构组件的基本用法和高级技术,这本书还提供了一些实际应用示例和案例分析。读者可以通过参考这些示例来更好地理解和应用Jetpack架构组件。 总之,《Jetpack架构组件从入门到精通》.pdf 是一本全面而深入地介绍Jetpack架构组件的书籍。无论是初学者还是有一定经验的开发者,都可以通过阅读这本书来提升自己在Android应用开发中使用Jetpack的能力。 ### 回答2: 《Jetpack架构组件从入门到精通》.pdf 是一本关于Jetpack架构组件的学习指南。Jetpack是Android开发中一套强大而且灵活的组件集合,旨在帮助开发者更轻松地构建高质量的Android应用程序。 该PDF文件从入门到精通地介绍了Jetpack架构组件的各个方面。首先,它向读者介绍了Jetpack的概念和使用场景,以帮助读者了解为什么应该学习和使用这些组件。 接下来,该指南逐一介绍了Jetpack架构组件的不同模块,包括ViewModel、LiveData、Room、Navigation等。它详细解释了每个组件的功能和用法,并通过实际示例演示了如何在项目中使用它们。 此外,该指南还提供了一些常见的最佳实践和实用技巧,以帮助读者更好地理解和运用Jetpack架构组件。它还包含了一些常见问题和解决方案,帮助读者避免在实践中遇到的常见问题。 最后,该指南还提供了一些参考资料和进一步学习资源,以帮助读者深入学习和掌握Jetpack架构组件。 总的来说,该《Jetpack架构组件从入门到精通》.pdf提供了一个全面而详尽的学习指南,帮助读者了解和应用Jetpack架构组件,使他们能够更高效地构建高质量的Android应用程序。无论是初学者还是有经验的开发者,该指南都是一个值得阅读和参考的资源。 ### 回答3: 《Jetpack架构组件从入门到精通》.pdf 是一本介绍Android Jetpack架构组件的电子书,它有助于开发者学习和理解如何使用这些组件来构建高质量、稳定的Android应用程序。 Jetpack架构组件是由谷歌开发的一组库,旨在帮助开发者简化Android应用的开发过程。它提供了一系列的工具和组件,涵盖了各个方面,包括界面设计、数据库、网络通信、数据绑定、后台处理等。 这本电子书从入门到精通地介绍了各个组件的使用方法和最佳实践。它首先详细介绍了Jetpack架构组件的核心概念和优势,让读者了解为什么要使用这些组件。 然后,电子书逐一介绍了常用的Jetpack组件,如Lifecycle、ViewModel、Room、LiveData、Navigation等。每个组件都被详细地讲解,包括其作用、使用方法和示例代码。读者可以通过跟随书中的案例来实际操作和理解这些组件的使用。 除了介绍各个组件,电子书还分享了一些进阶的使用技巧和开发经验。这些技巧包括如何优化应用性能、处理异步任务、实现数据缓存等。通过这些实用的技巧,开发者可以进一步提高应用的质量和用户体验。 总的来说,《Jetpack架构组件从入门到精通》.pdf 是一本很有价值的学习资料,对于想要深入学习和掌握Jetpack架构组件的开发者来说是必不可少的参考书籍。无论是初学者还是有经验的开发者,都可以从中获得知识和技能的提升。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值