生命周期感知型组件
解耦很大程度上表现为系统组件的生命周期与普通组件之间的解耦。普通组件在使用过程中通常需要依赖于系统组件的生命周期。因为普通组件无法主动获知系统组件的生命周期事件。
生命周期感知型组件可执行响应另一个组件(如Activity
和Fragment
)的生命周期状态的变化。
原来常规的做法是在Activity
和Fragment
的生命周期方法中实现依赖组件的操作。但这种模式会导致代码条理性很差而且会扩展错误。
生命周期感知型组件可将依赖的代码从生命周期方法 中移入到组件 本身中。
andoridx.lifecycle
软件包提供了可用于构建生命周期感知型组件的类和接口-这些组件可根据Activity
或Fragment
的当前生命周期状态自动调整期行为。
Lifecycle
Lifecycle原理:
LifecycleOwner(被观察者);LifecycleObserver(观察者)。
通过观察者模式,实现对页面生命周期的监听。
使用 Lifecycle 进行开发之前需要先在 build.gradle 中添加如下依赖代码
1 | dependencies { |
Lifecycle
是一个类,用于存储有关组件(如Activity
或Fragment
)的生命周期状态的信息,并允许其他对象观察此状态。
Lifecycle
使用两种主要枚举跟踪其关联组件的生命周期状态:
事件
从框架和 Lifecycle 类分派的生命周期事件。这些事件映射到 Activity 和 Fragment 中的回调事件。
状态
由 Lifecycle 对象跟踪的组件的当前状态。
可将状态看做图中的节点,事件看做这些节点之间的边。
类可通过向其方法添加注解来监控组件的生命周期状态。然后,通过调用 Lifecycle 类的 addObserver()
方法并传递观察者的实例来添加观察者
1 | public class MyObserver implements LifecycleObserver{ |
例子:
没有用生命周期感知组件的代码,可能是这样
1 | class MyLocationListener{ |
使用lifecycle组件的例子:
- 让需要感知生命周期的组件实现LifecycleObserver接口
1 | import androidx.lifecycle.Lifecycle; |
- 对应 Activity 或 Fragment 实现 LifecycleOwner,并调用 getLifecycle().addObserverLifecycle().addObserver 添加观察者
1 | import androidx.appcompat.app.AppCompatActivity; |
自定义生命周期组件
有一个自定义类想让它成为 LifecycleOwner,可以使用 LifecycleRegistry 类,但需要将事件转发到自己的类中
1 | import androidx.annotation.NonNull; |
LifecycleOwner
LifecycleOwner 是单一方法接口,表示类具有 Lifecycle。它具有一种方法 (即 getLifecycle()),该方法必须由类实现。如果您尝试管理整个应用进程的生命周期,请参阅 ProcessLifecycleOwner。
此接口从各个类(如 Fragment
和 AppCompatActivity
)抽象化 Lifecycle 的所有权,并允许编写与这些类搭配使用的组件。任何自定义应用类均可实现 LifecycleOwner 接口
实现 LifecycleObserver 的组件可与实现 LifecycleOwner 的组件完美配合,因为所有者可以提供生命周期,而观察者可以注册以观察生命周期。
生命周期感知型组件的最佳做法
- 使界面控制器(Activity 和 Fragment)尽可能保持精简。它们不应试图获取自己的数据,而应使用 ViewModel 执行此操作,并观察 LiveData 对象以将更改体现到视图中。
- 设法编写数据驱动型界面,对于此类界面,界面控制器的责任是随着数据更改而更新视图,或者将用户操作通知给 ViewModel。
- 将数据逻辑放在 ViewModel 类中。ViewModel 应充当界面控制器与应用其他部分之间的连接器。不过要注意,ViewModel不负责获取数据(例如,从网络获取)。但是,ViewModel 应调用相应的组件来获取数据,然后将结果提供给界面控制器。
- 使用数据绑定在视图与界面控制器之间维持干净的接口。这样一来,您可以使视图更具声明性,并尽量减少需要在 Activity 和 Fragment 中编写的更新代码。如果您更愿意使用 Java 编程语言执行此操作,请使用诸如 ButterKnife 之类的库,以避免样板代码并实现更好的抽象化。
- 如果界面 很复杂,不妨考虑创建 View 或 Activity 上下文。如果 ViewModel 存在的时间比 Activity 更长(在配置更改的情况下),Activity 将泄露并且不会获得垃圾回收期的妥善处置。
- 使用 Kotlin 协程 管理长时间运行的任务和其他可以一部运行的操作。
LifeCycles
让组件感知Activity、Fragment组件的生命周期,Activity进一步解耦
与Activity的生命周期同步的类实现 LifecycleObserver
,其中方法上分别加不同的注解标记是不同的生命周期。如@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
、@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
等等(对应了Activity的生命周期)
完整例子(一个显示在当前页面停留多少时间的例子):
MainActivity.kt
1 | /** |
activity_main.xml
1 |
|
MyChronometer.java
1 | package com.ab.lifecyclesdemo; |
新版SDK包中Activity、Fragment默认实现了LifecycleOwner接口。LifecycleOwner接口只有一个 getLifecycle(LifecycleObserver observer)
方法。
如果是要监听 Service 的生命周期,则可以让 自己的Service类实现 LifecycleOwner 接口,再重写的 getLifecycle() 方法中的返回
1 | public class LifecycleService extends Service implements LifecycleOwner{ |
1 | //使用 |
ProcessLifecycleOwner的具体用法
1 | dependencies{ |
1 | public class MyApplication extends Application{ |