Android 架构组件(一): Lifecycle
转载自 Android 架构组件(一)——Lifecycle-Aware Components
有一天“谷歌开发者”官微推送了《正式发布 Android 架构组件 1.0 稳定版 | 附带中文介绍视频》,发现这种架构足够秒杀MVP、MVVM,虽然之前的Google I/O大会中也介绍过,但是这次推出是稳定版,而且是可以投入到生产中去。于是就顺着这篇去官网看了使用文档——《Guide to App Architecture》。为了能够更好的理解架构组件的原理,准备先从Lifecycle入手,一步步去理解。
为什么需要Lifecycle组件
Lifecycle组件包括LifecycleOwner、LifecycleObserver。为什么需要Lifecycle组件?一项新的技术的提出肯定是为了解决痛点问题,如果使用过MVP模式的话,有个问题:Presenter感知Activity或者Fragment的生命周期?你可能会这样做,Presenter中定义多个和Activity或者Fragment相应的生命周期方法,然后在Activity或者Fragment中调用Presenter中定义的方法。比如下面的这个例子:
/**
* Main Presenter
*/
public class MainPresenter implements IPresenter {
public MainPresenter(Context context){
}
@Override
public void onCreate() {
}
@Override
public void onStart() {
}
@Override
public void onResume() {
}
@Override
public void onPause() {
}
@Override
public void onStop() {
}
@Override
public void onDestroy() {
}
}
public interface IPresenter {
void onCreate();
void onStart();
void onResume();
void onPause();
void onStop();
void onDestroy();
}
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private IPresenter mPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate: ");
setContentView(R.layout.activity_main);
mPresenter = new MainPresenter(this);
mPresenter.onCreate();
}
@Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart: ");
mPresenter.onStart();
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume: ");
mPresenter.onResume();
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause: ");
mPresenter.onPause();
}
@Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop: ");
mPresenter.onStop();
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy: ");
mPresenter.onDestroy();
}
}
上面的例子很容易理解,IPresenter中定义和生命周期相关的几个方法,然后在MainActivity中调用对应的方法。这样做会有个问题:在MainActivity中的每个生命周期方法中都要调用一次IPresenter中的接口,对于爱偷懒的程序员来说,这是不能接受的,所以Lifecycle组件就诞生了。
方式一: 继承DefaultLifecycleObserver(自测:找不到这个类,于是我用的是下面的方式二)
public class MainPresenter implements IPresenter {
private static final String TAG = "MainPresenter";
public MainPresenter(Context context){
}
@Override
public void onCreate(LifecycleOwner owner) {
Log.d(TAG, "onCreate: ");
}
@Override
public void onStart(LifecycleOwner owner) {
Log.d(TAG, "onStart: ");
}
@Override
public void onResume(LifecycleOwner owner) {
Log.d(TAG, "onResume: ");
}
@Override
public void onPause(LifecycleOwner owner) {
Log.d(TAG, "onPause: ");
}
@Override
public void onStop(LifecycleOwner owner) {
Log.d(TAG, "onStop: ");
}
@Override
public void onDestroy(LifecycleOwner owner) {
Log.d(TAG, "onDestroy: ");
}
}
public interface IPresenter extends DefaultLifecycleObserver{
}
方式二:直接继承LifecycleObserver 并配合注解,(自测:验证没毛病)
public class MainPresenter implements IPresenter {
private static final String TAG = MainPresenter.class.getSimpleName();
private Context context;
public MainPresenter(Context context) {
this.context = context;
}
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
public void onCreate(){
MLog.i(TAG,"ON_CREATE");
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onStart(){
MLog.i(TAG,"ON_START");
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void onResume(){
MLog.i(TAG,"ON_RESUME");
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void onPause(){
MLog.i(TAG,"ON_PAUSE");
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onStop(){
MLog.i(TAG,"ON_STOP");
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
public void onDestroy(){
MLog.i(TAG,"ON_DESTROY");
}
@OnLifecycleEvent(Lifecycle.Event.ON_ANY)
public void onAny(){
MLog.i(TAG,"ON_ANY");
}
}
public interface IPresenter extends LifecycleObserver{
}
以上两种方式,随便选择适合自己的,效果是一样的,下面是调用代码:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private IPresenter mPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate: ");
setContentView(R.layout.activity_main);
mPresenter = new MainPresenter(this);
getLifecycle().addObserver(mPresenter);
}
@Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart: ");
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume: ");
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause: ");
}
@Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop: ");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy: ");
}
}
MainPresenter实现IPresenter接口,在MainPresenter中,我把DefaultLifecycleObserver中生命周期的方法全实现了,也可以选择实现其中几个,比如你只关心MainActivity的onCreate() 和onDestroy(),那么你就可以在MainPresenter中实现onCreate()和onDestroy()方法。借助实现DefaultLifecycleObserver接口可以让我们少写很多代码。知道为什么需要Lifecycle组件后,你可能会问了,Lifecycle组件实现的原理是什么?这就是下面我要将的内容了。
Lifecycle组件原理
一般讲到原理,你可能会看到一堆文字的描述,然后就没有看下去的欲望了,能不能来点生动的,比如带点颜色的?好,我懂你,来张高清无码图。
我们以V4包中的Fragment(AppCompatActivity类似)为例,看下Fragment和LifecycleOwner、LifecycleObserver、Lifecycle之间的类关系图。
-
Lifecycle组件成员Lifecycle被定义成了抽象类,LifecycleOwner、LifecycleObserver被定义成了接口;
-
Fragment实现了LifecycleOwner接口,该只有一个返回Lifecycle对象的方法getLifecyle();
-
Fragment中getLifecycle()方法返回的是继承了抽象类Lifecycle的LifecycleRegistry。
LifecycleRegistry中定义嵌套类ObserverWithState,该类持有GenericLifecycleObserver对象,而GenericLifecycleObserver是继承了LifecycleObserver的接口。
对于Fragment、Lifecycle、LifecycleOwner、LifecycleObserver的关系有了一定了解后,可以看一个更直观的图,也就是下面的时序图:
-
我们在Fragment(AppCompatActivity也一样)中调用getLifecycle()方法得到LifecycleRegistry对象,然后调用addObserver()方法并将实现了LifecycleObserver接口的对象作为参数传进去。这样一个过程就完成了注册监听的过程。
-
后续就是Fragment生命周期变化时,通知LifecycleObserver的过程:Fragment的performXXX()、onXXX()方法;LifecycleRegistry的handleLifecycleEvent()方法;LifecycleObserver的onXXX()方法。
-
如果你细心点看上面的时序图,你会发现Fragment中performCreate()、performStart()、performResume()会先调用自身的onXXX()方法,然后再调用LifecycleRegistry的handleLifecycleEvent()方法;而在performPause()、performStop()、performDestroy()中会先LifecycleRegistry的handleLifecycleEvent()方法 ,然后调用自身的onXXX()方法。比如上面的例子中,打印出来的结果也确实符合我们的分析,打印结果如下:
12-01 14:12:59.250 1398-1398/com.shymanzhu.architecture D/MainActivity: onCreate:
12-01 14:12:59.342 1398-1398/com.shymanzhu.architecture D/MainPresenter: onCreate:
12-01 14:12:59.345 1398-1398/com.shymanzhu.architecture D/MainActivity: onStart:
12-01 14:12:59.345 1398-1398/com.shymanzhu.architecture D/MainPresenter: onStart:
12-01 14:12:59.346 1398-1398/com.shymanzhu.architecture D/MainActivity: onResume:
12-01 14:12:59.346 1398-1398/com.shymanzhu.architecture D/MainPresenter: onResume:
12-01 14:12:59.601 1398-1412/com.shymanzhu.architecture D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
12-01 14:12:59.609 1398-1398/com.shymanzhu.architecture I/imx6.gralloc: open gpu gralloc module!
12-01 14:12:59.847 1398-1412/com.shymanzhu.architecture I/OpenGLRenderer: Initialized EGL, version 1.4
12-01 14:13:27.348 1398-1398/com.shymanzhu.architecture D/MainPresenter: onPause:
12-01 14:13:27.349 1398-1398/com.shymanzhu.architecture D/MainActivity: onPause:
12-01 14:13:28.265 1398-1398/com.shymanzhu.architecture D/MainPresenter: onStop:
12-01 14:13:28.266 1398-1398/com.shymanzhu.architecture D/MainActivity: onStop:
12-01 14:13:28.267 1398-1398/com.shymanzhu.architecture D/MainPresenter: onDestroy:
12-01 14:13:28.267 1398-1398/com.shymanzhu.architecture D/MainActivity: onDestroy:
到现在为止,是不是觉得对大体的框架和流程更加清楚了呢,其实这个Lifecycle组件就是一套设计模式中观察者模式的例子。按道理说,到这里也差不多结束了,具体的细节就是去跟源码了(既然这么说了,肯定有“但是”,机智如你),但是我觉得还是有必要将一些细节说明下。
部分细节
LifecycleOwner、LifecycleObserver、Lifecycle的定义都很简洁,就没必要列举出来了,我们从流程图可以看出来,我们要做的内容主要是实现LifecycleObserver接口,然后通过实现了LifecycleOwner接口的对象进行注册,以监听其生命周期,后续就是坐等通知了。
实现LifecycleObserver接口
从上面的类关系图,我们可以看到有三个接口GenericLifecycleObserver、FullLifecycleObserver、DefaultLifecycleObserver都直接或者间接继承了LifecycleObserver。然而GenericLifecycleObserver是隐藏的,我们用不了。那我们该怎么实现LifecycleObserver接口呢,有两种方式:
- 实现DefaultLifecycleObserver接口,然后重写里面生命周期方法;
- 直接实现LifecycleObserver接口,然后通过注解的方式来接收生命周期的变化;
对于这两种形式,Lifecycle.java文档中是建议使用第一种方式,因为文档中说明了,随着Java8成为主流,注解的方式会被弃用。
添加观察者
实现LifecycleOwner没什么好说的,我们直接看添加观察者( addObserver() ),LifecycleRegistry实现了Lifecycle接口,addObserver()实现如下:
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
if (previous != null) {
return;
}
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
// it is null we should be destroyed. Fallback quickly
return;
}
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
popParentState();
// mState / subling may have been changed recalculate
targetState = calculateTargetState(observer);
}
if (!isReentrance) {
// we do sync only on the top level.
sync();
}
mAddingObserverCounter--;
}
在该方法中主要关注一点:
- 根据observer和initialState构造ObserverWithState对象statefulObserver,然后将该对象存入mObserverMap,可以简单的把它理解成用来保存观察者的Map。
坐等通知
添加观察者后,那观察者接下来就是坐等通知了。从上面的时序图中,我们看到Fragment是通过LifecycleRegistry.handleLifecycleEvent()方法通知LifecycleRegistry其生命周期的,那我们看下LifecycleRegistry的handleLifecycleEvent()相关的方法。
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);//计算下一个生命周期状态
moveToState(next);
}
private void moveToState(State next) {
if (mState == next) {
return;
}
mState = next;
if (mHandlingEvent || mAddingObserverCounter != 0) {
mNewEventOccurred = true;
// we will figure out what to do on upper level.
return;
}
mHandlingEvent = true;
sync(); //看下sync()方法的具体实现
mHandlingEvent = false;
}
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
Log.w(LOG_TAG, "LifecycleOwner is garbage collected, you shouldn't try dispatch "
+ "new events from it.");
return;
}
while (!isSynced()) {
mNewEventOccurred = false;
// no need to check eldest for nullability, because isSynced does it for us.
//比较当前的生命周期和Map中第一个的观察者的生命周期,下面的另一个if语句类似。
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
//看下forwardPass()方法
private void forwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
mObserverMap.iteratorWithAdditions();
while (ascendingIterator.hasNext() && !mNewEventOccurred) {
Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
ObserverWithState observer = entry.getValue();
while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
pushParentState(observer.mState);
observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
popParentState();
}
}
}
static class ObserverWithState {
State mState;
GenericLifecycleObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.getCallback(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event); //通知观察者生命周期变化。
mState = newState;
}
}
代码中大体的细节就是这样子,当然更细的内容只能通过你自己去了解了,建议明白Lifecycle组件的框架和结构后,再去看它实现的细节,而不是一上来就深究代码,那让会让你只见树木不见森林。
上一篇: Android 架构组件(一)——Lifecycle
下一篇: 有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡是报到3的人退出圈子,问最后留下来的是原来的第几位(指针方法处理)。
推荐阅读
-
android组件化架构(速览android组件和使用技巧)
-
android组件化架构(速览android组件和使用技巧)
-
Android项目实战(四十八):架构之组件化开发
-
Android 项目架构 组件化基础介绍
-
Android Jetpack架构组件之Lifecycle
-
阿里巴巴内部Jetpack宝典意外流出!极致经典,堪称Android架构组件的天花板
-
就在上周,联合十多位Android技术圈的小网红,做了一份Android架构师进阶书籍推荐!
-
tomcat组件图解 一个web服务器的架构演化史
-
我开源了一个基于Vue的组织架构树组件
-
集推流和流媒体RTSP服务于一身的同屏功能组件支持Windows,Android平台EasyScreenLive-Win同屏㢟开启屏幕采集失败解决方案