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不仅包含生命周期的状态信息,允许其他对象监听这个状态。
它使用两个枚举来关联生命周期的状态:
事件:其从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是一个只有一个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