Android Jetpack应用指南
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.2 使用LifeCycle解耦页面与组件

2.2.1 案例分析

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

从以上代码可以看出,获取地理位置这个需求的实现,与页面的生命周期息息相关。如果我们希望将获取地理位置这一功能独立成一个组件,那么生命周期是必须要考虑在内的。我们不得不在页面生命周期的各个回调方法中,对组件进行通知,因为组件不能主动感知生命周期的变化。

2.2.2 LifeCycIe的原理

LifeCycle是如何解决这个问题的呢?Jetpack为我们提供了两个类:LifecycleOwner(被观察者)和LifecycleObserver(观察者)。即通过观察者模式,实现对页面生命周期的监听。

通过查看SupportActivity的源码,可以看到,在新版本的SDK包中,Activity已经默认实现了LifecycleOwner接口。LifecycleOwner接口中只有一个getLifecycle(LifecycleObserver observer)方法,LifecycleOwner正是通过该方法实现观察者模式的。源码示例如下。

从以上源码可知,SupportActivity已经替我们实现了被观察者应该实现的那一部分代码。因此,我们不需要再去实现这部分代码。当我们希望监听Activity的生命周期时,只需要实现观察者那一部分的代码,即让自定义组件实现LifecycleObserver接口即可。该接口没有接口方法,无须任何具体实现。

2.2.3 解决方案

现在,让我们利用LifeCycle改写该需求。我们的目的是将该功能从Activity中独立出去,在减少耦合度的同时,又不影响对生命周期的监听。

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

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

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

就这么简单!LifeCycle完美解决了组件对页面生命周期的依赖问题,使组件能够自己管理其生命周期,而无须在页面中对其进行管理。这无疑大大降低了代码的耦合度,提高了组件的复用程度,也杜绝了由于对页面生命周期管理的疏忽而引发的内存泄漏问题,这在项目工程量大的情况下是非常有帮助的。

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