1、概述
google的jetpack已经出来很久了,最近项目中用接入后,也是遇到了不少坑。于是抽时间好好研究了下lifecycle、livedata、viewModel等源码,本文就来介绍一下lifecycle的用法及原理。
2、设计初衷
先来一句官方解释:android.arch.lifecycle 包提供了可以用于构建生命周期感知(lifecycle-aware)组件的类和接口,这些组件可以根据 Activity 或 Fragment 的当前生命周期自动调整其行为。
我的理解就是你可以用lifecycle使任何一个类具有生命周期。这个生命周期会跟随activity或fragment的生命周期。(其实并不一定要activity,只要实现lifecycleOwner既可,这个后面再说)
掏出一个官方的例子:
class MyLocationListener {
public MyLocationListener(Context context, Callback callback) {
// ...
}
void start() {
// 链接到系统定位服务
}
void stop() {
// 断开系统定位服务
}
}
class MyActivity extends AppCompatActivity {
private MyLocationListener myLocationListener;
public void onCreate(...) {
myLocationListener = new MyLocationListener(this, (location) -> {
// 更新 UI
});
}
public void onStart() {
super.onStart();
myLocationListener.start();
}
public void onStop() {
super.onStop();
myLocationListener.stop();
}
}
我们以前代码里常常出现类似这样的场景,看似没啥毛病,但很多这样的Listener会导致onstop之类的生命周期看起来臃肿,而且自己写起来也麻烦,于是lifecycle孕育而生。
3、基本使用
使用的话,总结为一句话:需要一个LifecycleOwner,和一个LifecycleObserver,然后观察起来就好了,这样LifecycleObserver就会跟随LifecycleOwner的生命周期了。所以上面的例子里MyActivity就是LifecycleOwner,MyLocationListener就是LifecycleObserver。用代码来表示就像这样:
class MyLocationListener implements LifecycleObserver {
public MyLocationListener(Context context, Callback callback) {
// ...
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
void start() {
// 链接到系统定位服务
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
void stop() {
// 断开系统定位服务
}
}
class MyActivity extends AppCompatActivity {
private MyLocationListener myLocationListener;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
myLocationListener = new MyLocationListener(this, (location) -> {
// 更新 UI
});
getLifecycle().addObserver(myLocationListener);
}
@Override
protected void onDestroy() {
super.onDestroy();
getLifecycle().removeObserver(myLocationListener);
}
}
其中AppCompatActivity已经实现了LifecycleOwner,无需我们自己操作。就像我上面说的一样,重点在于这一句:getLifecycle().addObserver(myLocationListener);
而实现LifecycleObserver的需要将自己的生命周期方法加上注释@OnLifecycleEvent。用法很简单,大致就是这样。这个方式主要用于你希望赋予某个类生命周期。比如MVP模式的presenter、MVVM模式的ViewModel,拥有生命周期后就可以在其中做一些释放内存之类的操作。
4、原理解析
注意是原理,而不是源码,受到某些影响,现在不喜欢大段大段贴源码的方式写作,感觉不仅难以理解还无法理解其思想。
lifecycle很明显是基于观察者模式,被观察者为LifecycleOwner,他只有一个方法:getLifecycle(); 具体实现,我们就挑google现成的例子:fragment。
fragment关于lifecycle的代码抽出来很简单:
public class Fragment implements xxx, LifecycleOwner {
LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
//...
void performCreate(Bundle savedInstanceState) {
onCreate(savedInstanceState);
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}
void performStart() {
onStart();
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
}
void performResume() {
onResume();
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
}
void performPause() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
onPause();
}
void performStop() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
onStop();
}
void performDestroy() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
onDestroy();
}
}
很明显,真正作为lifecycle的是LifecycleRegistry,fragment仅仅是将生命周期进行分发。而LifecycleRegistry确实是实现了Lifecycle,看看Lifecycle的设计:
public abstract class Lifecycle {
public abstract void addObserver(@NonNull LifecycleObserver observer);
public abstract void removeObserver(@NonNull LifecycleObserver observer);
public abstract State getCurrentState();
public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY
}
public enum State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
}
}
看起来也非常简洁,添加观察者、移除观察者、当前状态,以及event和state的设计。LifecycleRegistry实现了该接口,完成了观察者具体实现,这里就不详细解析了,可以自行学习源码。简单来说就是通过添加观察者,当生命周期改变时调用handleLifecycleEvent方法通知LifecycleObserver,并调用相关方法。
LifecycleObserver
接下来聊聊这个LifecycleObserver,google提供的实现方案有两种,在lifecycle类的注释上写的很清楚,
其一是和我们上面的实现方案:实现LifecycleObserver接口,在相关生命周期方法上加上OnLifecycleEvent注释,这种方案适用于JAVA7及以下,会根据注释利用APT编译期自动生成GeneratedAdapter实现类,只有一个方法callMethods,当生命周期改变时会回调该方法,并在该方法内回调我们注释过的相应的生命周期。底层还是利用GenericLifecycleObserver来实现的,这个我们后面再解析。
其二是实现DefaultLifecycleObserver,里面有相关的生命周期方法。适用于JAVA8以上,google推荐使用该类方案,因为当JAVA8成为Android主流后可能第一种方案就会被遗弃。
无论传入的是哪一种Observer,都会被包装成对应的Observer,关键代码在LifecycleRegistry的内部包装类ObserverWithState中
static class ObserverWithState {
State mState;
GenericLifecycleObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
//这里包装observer
mLifecycleObserver = Lifecycling.getCallback(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
//包装成GenericLifecycleObserver,生命周期改变时调用
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
}
我们来看看Lifecycling.getCallback(observer)是如何包装的:
@NonNull
static GenericLifecycleObserver getCallback(Object object) {
//第二种方案走这里,DefaultLifecycleObserver继承于FullLifecycleObserver
if (object instanceof FullLifecycleObserver) {
return new FullLifecycleObserverAdapter((FullLifecycleObserver) object);
}
//livedata的生命周期走这里,后面详解
if (object instanceof GenericLifecycleObserver) {
return (GenericLifecycleObserver) object;
}
//第一种方案走这里,通过apt方式生成的adapter类
final Class<?> klass = object.getClass();
int type = getObserverConstructorType(klass);
if (type == GENERATED_CALLBACK) {
List<Constructor<? extends GeneratedAdapter>> constructors =
sClassToAdapters.get(klass);
if (constructors.size() == 1) {
GeneratedAdapter generatedAdapter = createGeneratedAdapter(
constructors.get(0), object);
return new SingleGeneratedAdapterObserver(generatedAdapter);
}
GeneratedAdapter[] adapters = new GeneratedAdapter[constructors.size()];
for (int i = 0; i < constructors.size(); i++) {
adapters[i] = createGeneratedAdapter(constructors.get(i), object);
}
return new CompositeGeneratedAdaptersObserver(adapters);
}
return new ReflectiveGenericLifecycleObserver(object);
}
无论是哪一种方案,哪一种observer,都会去实现onStateChanged方法,我们拿第二种方案为例,看看FullLifecycleObserverAdapter中的实现:
class FullLifecycleObserverAdapter implements GenericLifecycleObserver {
private final FullLifecycleObserver mObserver;
FullLifecycleObserverAdapter(FullLifecycleObserver observer) {
mObserver = observer;
}
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
switch (event) {
case ON_CREATE:
mObserver.onCreate(source);
break;
case ON_START:
mObserver.onStart(source);
break;
case ON_RESUME:
mObserver.onResume(source);
break;
case ON_PAUSE:
mObserver.onPause(source);
break;
case ON_STOP:
mObserver.onStop(source);
break;
case ON_DESTROY:
mObserver.onDestroy(source);
break;
case ON_ANY:
throw new IllegalArgumentException("ON_ANY must not been send by anybody");
}
}
}
很明显,当onStateChanged被调用时,根据event回调我们实现的DefaultLifecycleObserver里的各种生命周期方法。其他方案类似,就不一一列出了。
理一下思路:
1、在LifecycleOwner中加入各种类型的observer观察者,LifecycleOwner真正实现是LifecycleRegistry。
2、在LifecycleRegistry中利用Lifecycling包装observer为GenericLifecycleObserver
3、调用GenericLifecycleObserver的onStateChanged方法进行event分发,这里有策略模式的影子
5、自定义LifecycleOwner
根据上一节原理以及google对fragment的实现,自定义LifecycleOwner就很简单了。总结为两句话:1、生成一个LifecycleRegistry。2、分发生命周期事件
加入我们要把dialog变成LifecycleOwner,就像这样:
public class baseDialog extends Dialog implements LifecycleOwner {
private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@NonNull
@Override
public Bundle onSaveInstanceState() {
mLifecycleRegistry.markState(Lifecycle.State.CREATED);
return super.onSaveInstanceState();
}
//...省略了其他生命周期
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}
@Override
protected void onStop() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
super.onStop();
}
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
}
6、LiveData的生命周期管理
LiveData是jetpack另外一个重要的组件,用于监听数据变更,UI做出相应响应,这里就不详细介绍了,他也是基于观察者模式,自然需要解绑避免内存泄漏。但他内部已经处理好生命周期,我们只管使用无须担心。自然,他就是用lifecycle来实现的。
我们前面提到lifecycle是赋予某个类生命周期才出现的,LiveData虽然无需那么多生命周期,但是可以利用他在LifecycleOwner(Activity...)ondestroy时同步解绑,就完成了LiveData的自动释放。
LiveData自己实现了observer:LifecycleBoundObserver,然后在onStateChanged方法里判断是否需要解绑即可。
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
//判断如果状态是DESTROYED就解绑
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
LiveData的源码也很简单,只有不到500行代码,还有不少一部分是注释,感兴趣可以自行阅读。
网友评论