Lifecycle 是用来管理和响应activity和Fragment生命周期的变化。我们通常在Activity和Fragment中生命周期方法中进行一些繁重操作,帮我们可以将这些生命周期的方法使用Lifecycle进行管理。它可以自动整合Activity和Fragment生命周期的状态。
添加依赖:
1.在project下的build.gradle中添加Maven仓库
allprojects { repositories { jcenter() google()//添加Google Maven仓库 } }
2.app下的build.gradle
dependencies { // ViewModel and LiveData implementation "android.arch.lifecycle:extensions:1.1.1" // alternatively, just ViewModel implementation "android.arch.lifecycle:viewmodel:1.1.1" // alternatively, just LiveData implementation "android.arch.lifecycle:livedata:1.1.1" annotationProcessor "android.arch.lifecycle:compiler:1.1.1" // Room (use 1.1.0-beta3 for latest beta) implementation "android.arch.persistence.room:runtime:1.0.0" annotationProcessor "android.arch.persistence.room:compiler:1.0.0" // Paging implementation "android.arch.paging:runtime:1.0.0-rc1" // Test helpers for LiveData testImplementation "android.arch.core:core-testing:1.1.1" // Test helpers for Room testImplementation "android.arch.persistence.room:testing:1.0.0" }
3.添加Java 8 支持
dependencies { // Java8 support for Lifecycles implementation "android.arch.lifecycle:common-java8:1.1.1" }
4.RXJava支持依赖
dependencies { // RxJava support for Room (use 1.1.0-beta3 for latest beta) implementation "android.arch.persistence.room:rxjava2:1.0.0" // ReactiveStreams support for LiveData implementation "android.arch.lifecycle:reactivestreams:1.1.1" // RxJava support for Paging implementation "android.arch.paging:rxjava2:1.0.0-alpha1" }
5.Guava依赖支持
dependencies { // Guava support for Room implementation "android.arch.persistence.room:guava:1.1.0-beta3" }6.轻量级Lifecycles支持
dependencies { // Lifecycles only (no ViewModel or LiveData) implementation "android.arch.lifecycle:runtime:1.1.1" annotationProcessor "android.arch.lifecycle:compiler:1.1.1" }
应用的生命周期大部分都是定义在Android Framework层,生命周期的管理是在操作系统或者是项目的框架层进行处理。否则会引发内存泄漏或者直接崩溃。例如:Activity中处理如下
class MyLocationListener { public MyLocationListener(Context context, Callback callback) { // ... } void start() { // connect to system location service } void stop() { // disconnect from system location service } } class MyActivity extends AppCompatActivity { private MyLocationListener myLocationListener; @Override public void onCreate(...) { myLocationListener = new MyLocationListener(this, (location) -> { // update UI }); } @Override public void onStart() { super.onStart(); myLocationListener.start(); // manage other components that need to respond // to the activity lifecycle 管理Activity的其他响应 } @Override public void onStop() { super.onStop(); myLocationListener.stop(); // manage other components that need to respond // to the activity lifecycle } }
然而在实际项目中,我们会有很多管理UI的回调和其他的响应生命周期的组件,在生命周期方法中会有很多很复杂的逻辑,不利于我们项目的维护。也不能保证Activity或Fragment在onStop()执行之前onStart()就会执行完成。
class MyActivity extends AppCompatActivity { private MyLocationListener myLocationListener; public void onCreate(...) { myLocationListener = new MyLocationListener(this, location -> { // update UI }); } @Override public void onStart() { super.onStart(); Util.checkUserStatus(result -> { // what if this callback is invoked AFTER activity is stopped? if (result) { myLocationListener.start(); } }); } @Override public void onStop() { super.onStop(); myLocationListener.stop(); } }
Lifecycle
Lifecycle不仅包含生命周期的状态信息,允许其他对象监听这个状态。
它使用两个枚举来关联生命周期的状态:
事件:其从Fragmentwork层和Lifecycle类开始分发事件,再将这些事件映射到Activity和Fragment的生命周期中
状态:状态就是跟踪的生命周期的状态。
类的生命周期状态需要通过注解的方式。如下
public class MyObserver implements LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) public void connectListener() { ... } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) public void disconnectListener() { ... } } myLifecycleOwner.getLifecycle().addObserver(new MyObserver());
ps:myLifecycleOwner对象是实现了LifecycleOwner接口的对象
LifecycleOwner
LifecycleOwner是一个只有一个getLifecycle()的接口。此外还有一个可以控制整个应用的类ProcessLifecycleOwner
这个接口拥有抽象了Lifecycle这个单独类的所有权,此接口对任何类都可以实现。
LicecycleObserver和LicecycleOwner一起使用一个用来提供生命周期,一个用来注册观察者观察
示例如下:
class MyActivity extends AppCompatActivity { private MyLocationListener myLocationListener; public void onCreate(...) { myLocationListener = new MyLocationListener(this, getLifecycle(), location -> { // update UI }); Util.checkUserStatus(result -> { if (result) { myLocationListener.enable(); } }); } }
但是假如有类似于Fragment的事物运行回调在Activity状态被释放掉之后开启或者做其他事情,这就是我们不希望看到的,所以我们 要做让Fragment的不回调。如下:
class MyLocationListener implements LifecycleObserver { private boolean enabled = false; public MyLocationListener(Context context, Lifecycle lifecycle, Callback callback) { ... } @OnLifecycleEvent(Lifecycle.Event.ON_START) void start() { if (enabled) { // connect } } public void enable() { enabled = true; if (lifecycle.getCurrentState().isAtLeast(STARTED)) { // connect if not connected } } @OnLifecycleEvent(Lifecycle.Event.ON_STOP) void stop() { // disconnect if connected } }
此时,LocationListener就拥有了类的完整的生命周期,如果我们在其他的Activity和Fragment中使用,只需要对他初始化就行。这样所有的操作都会交由它本类来处理。
自定义LifecycleOwner
自定义实现LifecycleOwner必须在在Support Library26.1.0之的版本进行实现
使用LifecycleRegistry将事件推进到自定义的LifecycleOwner中。
public class MyActivity extends Activity implements LifecycleOwner { private LifecycleRegistry mLifecycleRegistry; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mLifecycleRegistry = new LifecycleRegistry(this); mLifecycleRegistry.markState(Lifecycle.State.CREATED); } @Override public void onStart() { super.onStart(); mLifecycleRegistry.markState(Lifecycle.State.STARTED); } @NonNull @Override public Lifecycle getLifecycle() { return mLifecycleRegistry; } }
感知组件的最佳实践
1.保持Activity或Fragment的简洁,使用ViewModel来观察data和View
2.尝试编写数据驱动的UI,数据或者用户行为发生改变UIController会更新View,或者通知ViewModel
3.ViewModel时Google设计的专门用于Model层和View层进行交互的一个类,与数据相关的逻辑Google推荐使用ViewModel去做,PS:ViewModel本身是不能操作数据的,它的本质是通过调用相关的组件来通知UI controller.
4.使用Data Binding或者Butter Knife节省模板代码的抽取。
5.使用MVP模式进行解耦
6.避免在ViewModel中引用View或Activity的上下文,防止内存泄漏。
感知组件的用例
1.实现粗粒度和细粒度直接的切换。当Activity可见状态是切换为细粒度,当其退居到后台(即不可见)是开启粗粒度。LiveData这个类当用户的行为发生改变时,它会自动通知UI更新。
2.终止和开启视频缓冲。Licecycle-aware会在开始播放之前尽快的缓冲,在销毁时终止缓冲。
3.开启和停止网络连接。应用在前台或者后台是会自动连接网络或断开。
4.暂停和播放动画。应用在前台时会自动播放或暂停。
停止事件处理
当Lifecycle属于AppCompatActivity或Fragment时,其状态CREATE和ON_STOP的事件的分发是在APPCompatActivity或Fragment的onSaveInstanceState()被调用。
当ON_START被调用之前,同时Fragment或AppCompatActivity的状态会保存在onSaveInstanceState()中。
PS:如果在UI的状态保存过之后FragmentManger会抛异常。
如果观察者在STARTRD时或者之前关联Lifecycle,LiveData通过避免调用它的观察者来阻止这个边缘案例的出现。并且在isAtLeast()之前通知其观察者。
在beta2版本之前,AppCompatActivity在其onSaveInstanceState()之后,并且onStop()调用之前去跟新UI,Lifecycle此时处于未创建状态。bata2之后会在事件分发之前去检查Lifecycle的状态,获取此时实际的状态。
但是还有两个问题:
1.在API level 23之前或者更低版本下,Android系统即便被另一个Activity覆盖,它还是会保存上一个的状态。也就是说onSaveinstanceState()被调用了可能没有调用onStop()。这就产生了一个潜在的长时间间隔,观察者仍然认为Lifecycle是活动的,即它的UI状态不能被修改。
2.只要使用LiveData就必须使用beta2之后的版本。
官网地址:https://developer.android.google.cn/topic/libraries/architecture/lifecycle.html