Android架构之LifeCycle组件

LifeCycle的简介


Jetpack组件系列文章链接参考他人:https://blog.csdn.net/qq_43404873/article/details/109491168

LifeCycle可以帮助开发者创建可感知生命周期的组件。这样,组件便能够在其内部管理自己的生命周期,

从而降低模块间的耦合度,并降低内存泄漏发生的可能性

为什么要引入LifeCycle


举个例子,我们经常需要在页面的onCreate()方法中对组件进行初始化,在onPause()方法中停止组件,

而在页面的onDestroy()方法中对组件进行资源回收工作。这样的工作非常烦琐,会让页面与组件之间的耦合度变高。

但这些工作又不得不做,因为这可能会引发内存泄漏。

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

每次都是在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基本使用

编写一个名为MyLocationListener的类。该类就是我们自定义组件,我们需要让组件实现LifecycleObserver接口,与获取地理位置相关的代码再该类中完成

对于组件中那些需要再页面生命周期发送变化时得到通知的方法,我们需要在这些方法上使用@OnLifecycleEvent(Lifecycle.Event.ON_xxx)注解进行标识。这样,当页面生命周期发生变化时,这些被注解标识过的方法会被自动调用。

MyLocationListener 代码如下

MyLocationListener 代码

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

是不是很简单呢?LifeCycle完美解决了组件对页面生命周期的依赖问题。

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

LifeCycIeService基本介绍


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

LifecycleService的使用


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

dependencies {

    implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

}

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

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

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

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

6.千万别忘记了,需要在清单文件中(manifest)注册MyService

通过以上示例可以看出,当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中进行相关代码的编写。

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

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

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

Lifecycle.Event.ON_CREATE只会被调用一次,而Lifecycle.Event.ON_DESTROY永远不会被调用。

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

当应用程序从前台退到后台(用户按下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类,但需要将事件转发到该类。

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

如果是自定义的LifecycleOwner,想要实现对某个生命周期进行监听的话,需要使用lifecycleRegistry.markState(Lifecycle.State.xxxx);加入到监听队伍中.

比如说,我想对Activity中的onStart()方法进行监听,那么就需要将onStart()方法加入到监听队伍中, lifecycleRegistry.markState(Lifecycle.State.STARTED);

上面不是已经说明,LifecycleOwner必须需要实现一个getLifecycle()方法,改方法需要返回一个Lifecycle类型的值,也就是我们创建的lifecycleRegistry

具体代码如下

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


总结

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,490评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,581评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,830评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,957评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,974评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,754评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,464评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,357评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,847评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,995评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,137评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,819评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,482评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,023评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,149评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,409评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,086评论 2 355

推荐阅读更多精彩内容