Android Jetpack--lifecycle全解析

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行代码,还有不少一部分是注释,感兴趣可以自行阅读。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,576评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,515评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,017评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,626评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,625评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,255评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,825评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,729评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,271评论 1 320
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,363评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,498评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,183评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,867评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,338评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,458评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,906评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,507评论 2 359

推荐阅读更多精彩内容