Jetpack生命周期管理 - Lifecycle实战及源码分析

概述

这次我们来聊聊 Jetpack。具体地说是聊聊他的生命周期管理组件 LifeCycle,因为JetPack这个官方库还蛮大。这里不会再讲 Jetpack的前世今生,以及他的作用什么的。这里我们主要讲讲 LifeCycle的基本使用,以及用LifeCycle改进一下上次我们讲到的 MVP 的例子。然后从源码角度分析一下 LifeCycle是如何帮助 Activity 或 Fragment管理生命周期的。后续会继续推出分析 Jetpack其他组件的文章。

我们知道,我们在用某些模块进行数据加载的时候,往往需要去监听 Activity或 Fragment的生命周期。再根据生命周期的变化去调整数据加载或回调的策略。不使用组件来管理的话,一般我们可以在 Activity或 Fragment的生命周期回调方法里手动去调用模块的生命周期方法。这样页面的生命周期回调方法里可能就会出现大量这样的刻板代码,也不好管理。LifeCycle就用来解决这样的一些问题。

1、使用

使用 LifeCycle不用添加依赖了,因为已经内置了。如果要使用 Viewmodel和 Livedata则需要加依赖,这两个后续会有文章分析。

首先,既然是生命周期的监听,那就会有观察者和被观察者。被观察者需要实现的接口是 LifecycleOwner,也就是生命周期拥有者(Activity 或 Fragment)。这两者都实现了 LifecycleOwner接口,我们可以看一下 Activity 的父类 ComponentActivity:

public class ComponentActivity extends androidx.core.app.ComponentActivity implements
        LifecycleOwner,
        ...
        ...
        {

生命周期观察者需要实现的接口是 LifecycleObserver。下面我们就结合上次 MVP架构的例子,给 Presenter添加 LifeCycle生命周期监听方法。

首先让 BasePresenter实现观察者接口:

// 实现 LifecycleObserver
public class BasePresenter<V extends IView> implements LifecycleObserver {
    private V mView;
    public void attach(V iView) {
        this.mView = iView;
    }
    public void detach() {
        this.mView = null;
    }
    public V getView() {
        return mView;
    }
}

然后我们给 BasePresenter的实现类 Presenter添加几个生命周期的方法,并加上@OnLifecycleEvent注解:

//  Presenter.java

    // onCreate
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    public void onCreate(){
        Log.d(TAG, "-----------LifecycleObserver -- onCreate");
    }
    // onStart
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void onStart(){
        Log.d(TAG, "-----------LifecycleObserver -- onStart");
    }
    // onPause
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void onPause(){
        Log.d(TAG, "-----------LifecycleObserver -- onPause");
    }
    // onStop
    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void onStop(){
        Log.d(TAG, "-----------LifecycleObserver -- onStop");
    }
    // onDestroy
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void onDestroy(){
        Log.d(TAG, "-----------LifecycleObserver -- onDestroy");
    }

然后在 BaseMvpActivity初始化时添加观察者:

// BaseMvpActivity.java

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView();
        initView();
        initData();
        mPresenter = createP();
        //mPresenter.attach(this);
        // 注释 1, 添加观察者
        getLifecycle().addObserver(mPresenter);
    }
 @Override
    protected void onDestroy() {
        super.onDestroy();
        // mPresenter.detach();
        // 移除观察者
        getLifecycle().removeObserver(mPresenter);
    }

上次例子使用了模板设计模式,所以现在生命周期观察者的添加和移除也放在模板里了。
然后打开 Activity后退出,看打印结果:

com.ethan.mvpapplication D/Presenter: -----------LifecycleObserver -- onCreate
com.ethan.mvpapplication D/Presenter: -----------LifecycleObserver -- onStart
com.ethan.mvpapplication D/Presenter: -----------LifecycleObserver -- onPause
com.ethan.mvpapplication D/Presenter: -----------LifecycleObserver -- onStop
com.ethan.mvpapplication D/Presenter: -----------LifecycleObserver -- onDestroy

Demo: MVP

2、源码分析

下面我们来分析一下 Lifecycle生命周期监听的原理。简单粗暴,直接点进上面注释 1的getLifecycle()方法,看看干了啥:

//  ComponentActivity.java

private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }

返回的是一个 LifecycleRegistry 对象,我们可以点进去看。LifecycleRegistry 是抽象类 Lifecycle的实现类:

public abstract class Lifecycle {
        @MainThread
        public abstract void addObserver(@NonNull LifecycleObserver observer);
        @MainThread
        public abstract void removeObserver(@NonNull LifecycleObserver observer);
        @MainThread
        @NonNull
        public abstract androidx.lifecycle.Lifecycle.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 androidx.lifecycle.Lifecycle.State state) {
                return compareTo(state) >= 0;
            }
        }
    }

上面抽象类 Lifecycle 不仅包含了添加和移除观察者的方法,还包含了 Event 和 State 两个枚举。我们可以看到,Event 这个枚举包含了 Activity最主要的几个生命周期的方法。

下面我们继续看 LifeCycle是怎么监听生命周期的:

  public class ComponentActivity extends androidx.core.app.ComponentActivity implements
            LifecycleOwner,
            ......{

        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            ......
            // 注释 2, ComponentActivity注入 ReportFragment
            ReportFragment.injectIfNeededIn(this);
            ......
        }
        ......

        @Override
        public androidx.lifecycle.Lifecycle getLifecycle() {
            return mLifecycleRegistry;
        }
    }

按理说可以在上面的 ComponentActivity的各个生命周期回调中调用观察者的对应方法,但我们可以看到 ComponentActivity 这个类里并没有这样做。而是在上面注释 2处将当前Activity对象注入 ReportFragment中,我们看看ReportFragment干了啥:

 public class ReportFragment extends Fragment {
        private static final String REPORT_FRAGMENT_TAG = "androidx.lifecycle"
                + ".LifecycleDispatcher.report_fragment_tag";

        public static void injectIfNeededIn(Activity activity) {
            android.app.FragmentManager manager = activity.getFragmentManager();
            if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
                // 注释 3, 创建ReportFragment 添加到 Activity,使得生命周期与之同步
                manager.beginTransaction().add(new androidx.lifecycle.ReportFragment(), REPORT_FRAGMENT_TAG).commit();
                manager.executePendingTransactions();
            }
        }
        static androidx.lifecycle.ReportFragment get(Activity activity) {
            return (androidx.lifecycle.ReportFragment) activity.getFragmentManager().findFragmentByTag(
                    REPORT_FRAGMENT_TAG);
        }
        // 分发生命周期回调事件
        private void dispatchCreate(androidx.lifecycle.ReportFragment.ActivityInitializationListener listener) {
            if (listener != null) {
                listener.onCreate();
            }
        }
     ......
     ......
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            dispatchCreate(mProcessListener);
            dispatch(androidx.lifecycle.Lifecycle.Event.ON_CREATE);
        }

        @Override
        public void onStart() {
            super.onStart();
           // 注释 4,  开始调用观察者的生命周期
            dispatchStart(mProcessListener);
            dispatch(androidx.lifecycle.Lifecycle.Event.ON_START);
        }
       ......
       ......
        private void dispatch(androidx.lifecycle.Lifecycle.Event event) {
            Activity activity = getActivity();
            if (activity instanceof LifecycleRegistryOwner) {
                ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
                return;
            }

            if (activity instanceof LifecycleOwner) {
                androidx.lifecycle.Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
                if (lifecycle instanceof LifecycleRegistry) {
                    // 注释 5,生命周期事件分发
                    ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
                }
            }
        }
    }

上面注释 3处我们可以看到,这里创建了一个 Fragment,然后将 Fragment添加到 Activity中。这样的话,新创建的这个 Fragment和 Activity就可以同步生命周期。之后,在上面注释 4的地方,Fragment的各种生命周期的方法里就可以调用观察者(LifecycleObserver)的相关的生命周期方法了。

也就是说,ComponentActivity 创建了一个 ReportFragment ,并把生命周期回调的事务交给了Fragment。这sao操作是不是很熟悉?没错!我们之前分析过,Glide 也是这么管理生命周期的。

上面注释 5,我们再看看生命周期事件分发,看看观察者方法最终调用的地方:

  // LifecycleRegistry.java
    static class ObserverWithState {
        androidx.lifecycle.Lifecycle.State mState;
        LifecycleEventObserver mLifecycleObserver;
        ObserverWithState(LifecycleObserver observer, androidx.lifecycle.Lifecycle.State initialState) {
            // 获取 ReflectiveGenericLifecycleObserver对象
            mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
            mState = initialState;
        }

        void dispatchEvent(LifecycleOwner owner, androidx.lifecycle.Lifecycle.Event event) {
            ......
            // 生命周期回调事件分发
            mLifecycleObserver.onStateChanged(owner, event);
        }
    }

    // Lifecycling.java
    static LifecycleEventObserver lifecycleEventObserver(Object object) {
        .....
        // 返回 ReflectiveGenericLifecycleObserver对象
        return new androidx.lifecycle.ReflectiveGenericLifecycleObserver(object);
    }

    // ReflectiveGenericLifecycleObserver.java
    class ReflectiveGenericLifecycleObserver implements LifecycleEventObserver {
        private final Object mWrapped;
        private final ClassesInfoCache.CallbackInfo mInfo;
        ReflectiveGenericLifecycleObserver(Object wrapped) {
            mWrapped = wrapped;
            mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());
        }

        @Override
        public void onStateChanged(LifecycleOwner source, androidx.lifecycle.Lifecycle.Event event) {
            // 生命周期回调
            mInfo.invokeCallbacks(source, event, mWrapped);
        }
    }

    // ClassesInfoCache.java
    private ClassesInfoCache.CallbackInfo createInfo(Class klass, @Nullable Method[] declaredMethods) {
        Class superclass = klass.getSuperclass();
        for (Method method : methods) {
            // 反射遍历观察者的各个方法,将带 @OnLifecycleEvent注解的方法保存在
            // Map对象中,方便生命周期变化时调用
            OnLifecycleEvent annotation = method.getAnnotation(OnLifecycleEvent.class);
            if (annotation == null) { continue; }
            Class<?>[] params = method.getParameterTypes();
            ......
            androidx.lifecycle.Lifecycle.Event event = annotation.value();
            ......
            ClassesInfoCache.MethodReference methodReference = new ClassesInfoCache.MethodReference(callType, method);
            verifyAndPutHandler(handlerToEvent, methodReference, event, klass);
            mCallbackMap.put(klass, info);
            mHasLifecycleMethods.put(klass, hasLifecycleMethods);
        }
        ......
        return info;
    }
    static class CallbackInfo {
        final Map<androidx.lifecycle.Lifecycle.Event, List<ClassesInfoCache.MethodReference>> mEventToHandlers;
        final Map<ClassesInfoCache.MethodReference, androidx.lifecycle.Lifecycle.Event> mHandlerToEvent;

        CallbackInfo(Map<ClassesInfoCache.MethodReference, androidx.lifecycle.Lifecycle.Event> handlerToEvent) {
            mHandlerToEvent = handlerToEvent;
            mEventToHandlers = new HashMap<>();
            for (Map.Entry<ClassesInfoCache.MethodReference, androidx.lifecycle.Lifecycle.Event> entry : handlerToEvent.entrySet()) {
                androidx.lifecycle.Lifecycle.Event event = entry.getValue();
                List<ClassesInfoCache.MethodReference> methodReferences = mEventToHandlers.get(event);
                if (methodReferences == null) {
                    methodReferences = new ArrayList<>();
                    mEventToHandlers.put(event, methodReferences);
                }
                methodReferences.add(entry.getKey());
            }
        }

        @SuppressWarnings("ConstantConditions")
        void invokeCallbacks(LifecycleOwner source, androidx.lifecycle.Lifecycle.Event event, Object target) {
            invokeMethodsForEvent(mEventToHandlers.get(event), source, event, target);
            invokeMethodsForEvent(mEventToHandlers.get(androidx.lifecycle.Lifecycle.Event.ON_ANY), source, event,
                    target);
        }

        private static void invokeMethodsForEvent(List<ClassesInfoCache.MethodReference> handlers,
                                                  LifecycleOwner source, androidx.lifecycle.Lifecycle.Event event, Object mWrapped) {
            if (handlers != null) {
                for (int i = handlers.size() - 1; i >= 0; i--) {
                    // 调用 MethodReference的 invokeCallback方法
                    handlers.get(i).invokeCallback(source, event, mWrapped);
                }
            }
        }
    }
    
    // ClassesInfoCache.MethodReference
    static class MethodReference {
        final int mCallType;
        final Method mMethod;
        .......
        void invokeCallback(LifecycleOwner source, androidx.lifecycle.Lifecycle.Event event, Object target) {
            //noinspection TryWithIdenticalCatches
            try {
                switch (mCallType) {
                    case CALL_TYPE_NO_ARG:
                        mMethod.invoke(target);
                        break;
                    case CALL_TYPE_PROVIDER:
                        mMethod.invoke(target, source);
                        break;
                    case CALL_TYPE_PROVIDER_WITH_EVENT:
                        mMethod.invoke(target, source, event);
                        break;
                }
            } catch (InvocationTargetException e) {
                throw new RuntimeException("Failed to call observer method", e.getCause());
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
    }

时序图就不画了,大概写一下调用流程吧:

LifecycleRegistry.java
--> handleLifecycleEvent();
--> moveToState(next);
--> sync();
--> forwardPass(lifecycleOwner);
--> LifecycleRegistry.ObserverWithState --> dispatchEvent(owner, event);

ReflectiveGenericLifecycleObserver .java
--> onStateChanged()

ClassesInfoCache.java
--> CallbackInfo createInfo(); (反射将观察者带注解的方法保存)

MethodReference.java
-->invokeCallback(source, event, mWrapped);
--> mMethod.invoke(target); (反射调用观察者的生命周期的方法)

经过层层调用和包装,注册时最终会用反射将观察者带@OnLifecycleEvent注解的方法保存在MethodReference中,并放入HashMap。当 Activity生命周期改变时,随着层层调用,最终保存在集合里的观察者LifecycleObserver生命周期相关方法会被调用。

这波sao操作是不是又似曾相识?没错!EventBus也是这么管理订阅和发送事件的。

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

推荐阅读更多精彩内容