Android官方架构组件介绍之Lifecycle的使用详解

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的生命周期中

状态:状态就是跟踪的生命周期的状态。

Android官方架构组件介绍之Lifecycle的使用详解_第1张图片

类的生命周期状态需要通过注解的方式。如下

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

你可能感兴趣的:(Android官方架构组件介绍之Lifecycle的使用详解)