Jetpack 源码分析(一) - Lifecycle源码分析

  从今天开始,楼主正式开始分析Jetpack各个组件的源码。在学习jetpack源码之前,我已经将官方的相关文档以及博客看了一遍,并且结合自己所理解的jetpack,花了差不多4个月时间完成了一个mvvm框架,有兴趣的同学可以去看看:mvvm - mvvm框架的入门使用
  jetpack组件是google爸爸在2018年的开发者大会上推出来的,在当时我就简单的学习过。说句实话,在那时我就想学习jetpack的源码,但是幸好并没有做。因为我知道,如果当时来写这个系列的文章,肯定会敷衍了事,写得会跟屎一样的,原因如下:

  1. 虽然当时就学过了jetpack,但是只是简单的入门,并不是真正的掌握。看一个库的源码切忌的是好高骛远,如果自己都不是很熟悉库的使用,就那么贸然的学习源码,肯定是一头雾水,写出来的文章肯定也是错误斑斑。
  2. 当时已经在学习RecyclerView的源码,如果中途又去学习别的东西,RecyclerView的学习计划岂不是要中途夭折。这是我最不想看到的结果,因为在写RecyclerView源码分析的系列文章时,我就给自己暗暗的立下了Flag,要写成全网最好的源码分析文章。

  那为什么现在要来写这个系列的文章呢?因为我觉得时机成熟了,原因如下:

  1. 我现在对jetpack库的使用已经有了一个比较熟悉的掌握,比如说,看完了官方相关的文档和博客,以及使用其完成了一个mvvm框架。
  2. 现在网络上相关的博客已经足够丰富了,这样我在看源码的时候可以作为参考。我觉得,看源码不是闭门造车,而是集百家之长,一定要明白一个道理:他山之石,可以攻玉。

  本系列文章楼主从几个方面来说起。先是介绍Lifecycle,然后是LiveData、ViewModel、paging。这其中paging组件里面还有DataSource相关组件,也会深入的分析。在分析源码的同时,我也会根据我的经验和所学到的知识尽可能的列举出,这其中可能到遇到的坑。


  感觉废话有点多了,现在我们正式开始学些Lifecycle的使用和源码。本文打算从下面几个方面来介绍Lifecycle:

  1. Lifecycle的介绍和基本使用。
  2. Lifecycle及其相关库之前的关系,比如说:Activity/Fragment、LifecycleOwner 、LifecycleRegistry以及LifecycleObserver都是啥,它们之间的关系又是啥。
  3. 状态的维持和分发。
  4. 使用Lifecycle需要注意的坑。

  本文参考文章:

  1. 使用生命周期感知型组件处理生命周期
  2. [Reveal]Lifecycle源码分析

  注意:本文的Lifecycle相关源码均来自于2.2.0版本,其他系统源码均是androidx包下的

1. 概述

  在正式分析Lifecycle的源码之前,我们先来了解一个Lifecycle到底是一个什么东西,Google爸爸为啥要搞一个这么一个东西。
  我们都知道,Activity和Fragment都有对应的生命周期,我们可以在每个生命周期里面做对应的事情。比如说,在Activity的onCreate方法里面,我们启动一个service服务,然后在onDestroy方法关闭这个服务。诸如此类的事情,如果我们都在Activity和Fragment做,自然显得比较简单,但是不可避免的就是Activity和Fragment都会显得非常沉重。
  在MVC的时代,我们只能这么做,但是现在MVP和MVVM框架下,我们不能这么做。同一部分业务逻辑应该收敛在同一个地方,不应该散落在工程的各个地方,所以Presenter和ViewModel需要感知Activity和Fragment就会显得尤为重要。
  在Lifecycle出现之前,或许我们已经有了对应的解决方法,比如说:

class MainActivity : AppCompatActivity() {
    private val mLifecycleObserverList = ArrayList<LifecycleObserver>()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        mLifecycleObserverList.forEach {
            it.onCreate()
        }
    }

    override fun onStart() {
        super.onStart()
        mLifecycleObserverList.forEach {
            it.onStart()
        }
    }

    override fun onResume() {
        super.onResume()
        mLifecycleObserverList.forEach {
            it.onResume()
        }
    }

    override fun onStop() {
        super.onStop()
        mLifecycleObserverList.forEach {
            it.onStop()
        }
    }

    override fun onPause() {
        super.onPause()
        mLifecycleObserverList.forEach {
            it.onPause()
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        mLifecycleObserverList.forEach {
            it.onDestroy()
        }
    }
}

  这种方法不可否认的是比较简单,但是不得不承认的是它也有对应的缺点:

  1. 侵入性太强。如果使用这种方式来实现,我们需要去修改Activity的代码,代价太大。
  2. 之前的状态不能同步。例如,我们在onStart的时候给添加一个Observer,onCreate的方法不会被回调,因为Activity的onCreate方法已经调用了。如果我们强依赖onCreate方法的话,我们还需要做一些特殊的逻辑来判断onCreate方法已经调用过了。例如,我们有一个Observer实在onCreate方法里面对应变量进行初始化,然后在onResume方法执行一些逻辑,如果这个Observer是在ActivityonCreate方法之后添加的,那么Observer对应的onCreate方法就不会再调用,那么初始化的操作就不会执行,在onResume方法中执行逻辑就会出错。

  如果我们使用Lifecycle来实现我们的业务逻辑,就没有如上的问题,因为Google爸爸已经帮助我们解决了。在正式分析它的实现原理,我们先来看看Lifecycle的基本使用吧。
  如果我们想要监听Activity和Fragment的生命周期,可以通过调用Activity和Fragment的getLifecycle方法来获得一个Lifecycle的对象,然后给其添加生命周期的观察者即可。例如:

class DemoPresenter(private val mActivity: AppCompatActivity) {

    fun onBind() {
        mActivity.lifecycle.addObserver(object : LifecycleObserver {
            @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
            fun onResume() {
                Log.i("jade", "onResume")
            }
        })
    }
}

  我们想要监听什么生命周期,就在对应的方法上加上对应的注解即可。例如在上面的例子当中,我们监听的是onResume方法。
  总的来说,Lifecycle的使用时非常简单的,接下来,我们将深入源码,透析其其本质。看了源码之后,你会发现,简单的背后是复杂的实现。

2. LifecycleOwner、LifecycleRegistry和LifecycleObserver之间的关系

  在看源码之前,我们需要先缕清LifecycleOwnerLifecycleRegistryLifecycleObserver三者的关系

类名 解释
LifecycleOwner 顾名思义,之后生命周期的持有者,Activity和Fragment均实现该接口。实现该接口,表示该组件是感知生命周期的,同时支持外部其他组件监听其生命周期。
LifecycleRegistry LifecycleRegistry是Lifecycle的实现类,主要负责生命周期持有者的状态维护和分发。
LifecycleObserver 生命周期变化的观察者,需要监听生命周期变化的组件,可以通过实现该接口,来监听每个生命周期的变化。

  在这其中,Activity和Fragment实现了LifecycleOwner接口,返回的对象就是一个LifecycleRegistry对象,而我们向Activity和Fragment里面添加生命周期观察者,就是往LifecycleRegistry里面添加观察者。
  关于生命周期的维护和分发,Google爸爸就定义了三个接口,这是为啥呢?这样做的好处,每个部分只关心接口定义部分,不关心接口实现部分,有一个好处就是后续再扩展就非常的方便,比如说Activity和Fragment面对的是LifecycleOwner接口,具体由谁实现,怎么实现,它不用知道。比如说现在的实现者是LifecycleRegistry,未来的实现者就有可能是LifecycleRegistryV2,同时也给我们留了很大扩展空间,比如说我们重写getLifecycle方法,返回一个我们自己实现的LifecycleRegistry对象,这样对Activity和Fragment本身没有任何影响。
  总的来说,三者关系如下:

3. 状态的维护和分发

(1). Activity和Fragment向LifecycleRegistry分发Event

  缕清主要类之间的关系之后,我们现在就来看看源码,看看Lifecycle内部是怎么对生命周期进行维护和分发的。我们先从Activity里面看起,Activity本身没有实现LifecycleOwner接口,而是它的子类--ComponentActivity

public class ComponentActivity extends Activity implements LifecycleOwnert {

    private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

    @Override
    @SuppressWarnings("RestrictedApi")
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ReportFragment.injectIfNeededIn(this);
    }

    @CallSuper
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        mLifecycleRegistry.markState(Lifecycle.State.CREATED);
        super.onSaveInstanceState(outState);
    }

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

  我们从ComponentActivity的源码中,可以看到关于状态分发的实现其实非常简单,就做了如下三件事:

  1. 实现LifecycleOwnert接口,并且getLifecycle方法返回LifecycleRegistry对象。
  2. onCreate方法里面加了一个ReportFragment。Google爸爸利用Fragment可以同步Activity的特性,使用ReportFragment来实现状态的同步。
  3. onSaveInstanceState方法里面调用LifecycleRegistrymarkState方法,Google爸爸这么做的目的是为了解决一个特殊的case。这里我先卖一下关子,后面再来解释他。

  从上面的代码中,我们可以看到,Activity内部并没有做多少事情,真正的实现都在ReportFragment里面。我们再来看看ReportFragment的源码:

public class ReportFragment extends Fragment {
    public static void injectIfNeededIn(Activity activity) {
        if (Build.VERSION.SDK_INT >= 29) {
            // On API 29+, we can register for the correct Lifecycle callbacks directly
            activity.registerActivityLifecycleCallbacks(
                    new LifecycleCallbacks());
        }
        // Prior to API 29 and to maintain compatibility with older versions of
        // ProcessLifecycleOwner (which may not be updated when lifecycle-runtime is updated and
        // need to support activities that don't extend from FragmentActivity from support lib),
        // use a framework fragment to get the correct timing of Lifecycle events
        android.app.FragmentManager manager = activity.getFragmentManager();
        if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
            manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
            // Hopefully, we are the first to make a transaction.
            manager.executePendingTransactions();
        }
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        dispatchCreate(mProcessListener);
        dispatch(Lifecycle.Event.ON_CREATE);
    }

    @Override
    public void onStart() {
        super.onStart();
        dispatchStart(mProcessListener);
        dispatch(Lifecycle.Event.ON_START);
    }

    @Override
    public void onResume() {
        super.onResume();
        dispatchResume(mProcessListener);
        dispatch(Lifecycle.Event.ON_RESUME);
    }

    @Override
    public void onPause() {
        super.onPause();
        dispatch(Lifecycle.Event.ON_PAUSE);
    }

    @Override
    public void onStop() {
        super.onStop();
        dispatch(Lifecycle.Event.ON_STOP);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        dispatch(Lifecycle.Event.ON_DESTROY);
        // just want to be sure that we won't leak reference to an activity
        mProcessListener = null;
    }

    private void dispatch(@NonNull Lifecycle.Event event) {
        if (Build.VERSION.SDK_INT < 29) {
            // Only dispatch events from ReportFragment on API levels prior
            // to API 29. On API 29+, this is handled by the ActivityLifecycleCallbacks
            // added in ReportFragment.injectIfNeededIn
            dispatch(getActivity(), event);
        }
    }
}

  我们乍一看ReportFragment的源码,感觉还挺简单的,就是在对应的生命周期里面dispatch不同的event。其实这只看到一层含义,还有一层含义,那就是在injectIfNeededIn方法里面:

    public static void injectIfNeededIn(Activity activity) {
        if (Build.VERSION.SDK_INT >= 29) {
            // On API 29+, we can register for the correct Lifecycle callbacks directly
            activity.registerActivityLifecycleCallbacks(
                    new LifecycleCallbacks());
        }
    }

  那就是如果API在29及其以上,不会走Fragment的生命周期,而是直接走LifecycleCallbacks的回调。不管哪种方式来实现,我们从源码中可以看到,归根结底都是走到了dispatch方法里面去了,我们来看看dispatch方法:

    static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
        if (activity instanceof LifecycleRegistryOwner) {
            ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
            return;
        }

        if (activity instanceof LifecycleOwner) {
            Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
            if (lifecycle instanceof LifecycleRegistry) {
                ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
            }
        }
    }

  最终的实现就是获取Activity的LifecycleOwner对象,进而调用它的handleLifecycleEvent方法来实现状态的分发。

(2). LifecycleRegistry向LifecycleObserver分发状态

  看完了Activity和Fragment的分发,我们感觉都还比较简单,但是这些毕竟都是状态分发的上游,现在还没有接触下游的观察者。那么在哪里向下游的观察者的分发呢?答案就是LifecycleRegistry。由于Activity和Fragment跟LifecycleRegistry通信都是通过handleLifecycleEvent方法,我们就从这个方法入手,来看看LifecycleRegistry的本质:

    public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
        State next = getStateAfter(event);
        moveToState(next);
    }

  在handleLifecycleEvent方法里面一共做了两件事:

  1. 根据getStateAfter方法,将handleLifecycleEvent方法传递进来的event,映射出下一个状态。例如,event为ON_CREATEON_STOP,对应的State就是CREATED,表示当前状态将转移到CREATED状态。
  2. 调用moveToState方法,实现状态的迁移。

  关于getStateAfter方法,我需要补充一下相关的知识。在Lifecycle内部有两种非常的枚举:StateEventState表示当前生命周期所处的状态,Event是作为状态(State)迁移的中间媒介。比如说,当前Activity处于CREATED状态,当接收到ON_START的Event,状态就会迁移到STARTED。Google爸爸的一张图可以很好的说明他们之间迁移的关系:


   宏观上来,LifecycleRegistry是内聚性非常高的类,对外通信都是通过Event来实现的,这其中包括与Activity和Fragment的通信、与LifecycleObserver的通信,外部类不应该有State这个枚举的所在。
   但是有细心的同学可能会有疑问,这不对啊,在ComponentActivityonSaveInstanceState方法中,是通过markState方法来通信。对此,我的理解是Google爸爸在整理代码时,可能漏掉了,理论上都应该通过Event来作为通信的媒介。理由是,Google爸爸将markState标记为过时了,我相信在不久的未来,setCurrentState方法也会过时。
   可能有同学还有疑问,为什么Google爸爸在不遗余力的搞一个State枚举,全都用Event通信不可以吗?如果中间设置一个State,还有做EventState的映射和StateEvent的映射。我认为,有如下两点理由:

  1. 从本质来说,Activity和Fragment的状态本身只有几种:1.初始化状态;2. 创建状态;3. 未激活状态;4. 激活状态;5. 销毁状态。生命周期之所以比状态多,而是为了让开发者能正确把握每个生命状态,而在LifecycleRegistry内部没必要定义这么多的状态,我们都知道onStartonStop是对应的,同理onResumeonPause是对应的。
  2. 有利于状态同步。比如说有一个LifecycleObserver是在onResume阶段被添加进来的,正常来说,前面的onCreateonStart都应该正常被调用,最后才调用onResume

  接下来我们继续看一下moveToState方法,关于状态的同步,我们可以在这个方法里面找到想要的答案。

    private void moveToState(State next) {
        if (mState == next) {
            return;
        }
        mState = next;
        if (mHandlingEvent || mAddingObserverCounter != 0) {
            mNewEventOccurred = true;
            return;
        }
        mHandlingEvent = true;
        sync();
        mHandlingEvent = false;
    }

  从上面的代码中,我们可以看到除了对sync方法的调用,还有其他的各种限制。对于这种限制,我们没有必要去深入理解它,这些限制肯定都是Google爸爸为了某些case而加的,所以我们的注意点应该放在sync方法上。

    private void sync() {
        LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
        if (lifecycleOwner == null) {
            throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
                    + "garbage collected. It is too late to change lifecycle state.");
        }
        while (!isSynced()) {
            mNewEventOccurred = false;
            // no need to check eldest for nullability, because isSynced does it for us.
            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;
    }

  从上面的源码中,我们可以看出来,sync方法主要做的是:将状态的更新分发到每个LifecycleObserver。不过,在分发过程中,我们发现几个有意思的地方:

  1. 在分发时需要调用isSynced方法来判断是否继续分发。相信大家都看了isSynced方法源码:
    private boolean isSynced() {
        if (mObserverMap.size() == 0) {
            return true;
        }
        State eldestObserverState = mObserverMap.eldest().getValue().mState;
        State newestObserverState = mObserverMap.newest().getValue().mState;
        return eldestObserverState == newestObserverState && mState == newestObserverState;
    }

大家可能有疑问,isSynced方法判断依据在哪里呢?这就牵扯到addObserver方法了,也就是添加观察者的方法。我在这里简单的解释一下原因吧,所有的观察者都放在一个叫FastSafeIterableMap的数据结构里面,这个数据结构的本质就是Map + 链表的结合,其中这个链表每个节点都是根据State从大到小排序的,就可以分为如下几种情况:
(1). 如果头结点和尾节点状态是一样的,同时跟LifecycleRegistry的当前状态一样,那么就不需要分发。
(2). 如果头结点和尾节点状态是一样的,但是跟LifecycleRegistry的当前状态不一样,此时就需要分发。这其中,如果头结点小于LifecycleRegistry的当前状态,那么整个链表上所有的LifecycleObserver都需要前进,就是调用forwardPass方法;如果尾节点大于LifecycleRegistry的当前状态,那么整个链表上所有的LifecycleObserver都需要前进,就是调用backwardPass方法;如果属于中间的情况,就是头结点大于LifecycleRegistry的当前状态, 尾节点小于LifecycleRegistry的当前状态,那么就是有的需要前进,有的需要后退。

  1. 还有有意思的地方就是backwardPassforwardPass方法的调用。backwardPass方法的作用后退状态,比如说当前有的LifecycleObserver处于onResume状态,此时Activity的状态更新为onPause状态,对应的需要后退,就如上面状态迁移图一样的;同理forwardPass方法与backwardPass是相反的。

  backwardPassforwardPass方法就是LifecycleRegistryLifecycleObserver分发状态的核心所在,这里我们就选择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();
            }
        }
    }

  在这里,我们就不深入分析它的内部实现和细节,我们就从两个方法入手,分别是:dispatchEvent方法和upEvent

  1. forwardPass方法内部,我们首先看到通过调用upEvent方法来获取观察者下一个状态的Event。这里相当于做了一次State到Event的映射。
  2. 调用了ObserverWithStatedispatchEvent,实现了将状态分发到每个LifecycleObserver

(3). LifecycleObserver状态的分发

  其实,在LifecycleRegistry内部,不是直接存储每个LifecycleObserver,而是将每个LifecycleObserver包装在一个名叫ObserverWithState的类里面。ObserverWithState类定义了两个变量,一个是State,表示的意思当前观察者所处的状态,LifecycleRegistry在同步状态是有一步操作就是更新这个变量;另一个变量就是一个LifecycleEventObserver对象,这个对象主要做了两件事:1. Event的更新;2. 添加观察者对象对应方法的回调。
  我们来看一下具体的实现,首先来看ObserverWithStatedispatchEvent方法,因为LifecycleRegistry通过该方法进行状态的分发:

        void dispatchEvent(LifecycleOwner owner, Event event) {
            State newState = getStateAfter(event);
            mState = min(mState, newState);
            mLifecycleObserver.onStateChanged(owner, event);
            mState = newState;
        }

  在dispatchEvent方法里面,主要做了两件事:

  1. 更新mState
  2. 将Event分发到LifecycleEventObserver里面去。

  LifecycleEventObserver本身就是一个适配器角色的存在,因为它的内部对可能存在的几种观察者类型都一一的做了判断,我们来详细看看:

    static LifecycleEventObserver lifecycleEventObserver(Object object) {
        boolean isLifecycleEventObserver = object instanceof LifecycleEventObserver;
        boolean isFullLifecycleObserver = object instanceof FullLifecycleObserver;
        // 1.LifecycleEventObserver和FullLifecycleObserver类型, 直接调用对应的方法,并且还会调用onStateChanged方法。
        if (isLifecycleEventObserver && isFullLifecycleObserver) {
            return new FullLifecycleObserverAdapter((FullLifecycleObserver) object,
                    (LifecycleEventObserver) object);
        }
        // 2. FullLifecycleObserver类型,直接调用对应的方法,与1的区别在于不会调用onStateChanged方法。
        if (isFullLifecycleObserver) {
            return new FullLifecycleObserverAdapter((FullLifecycleObserver) object, null);
        }
        // 3. LifecycleEventObserver类型,只会调用onStateChanged方法
        if (isLifecycleEventObserver) {
            return (LifecycleEventObserver) object;
        }

        final Class<?> klass = object.getClass();
        int type = getObserverConstructorType(klass);
        // 4. 通过生成的类实现回调(APT生成的?),也是通过直接调用方法实现
        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);
        }
        // 5. 直接反射调用
        return new ReflectiveGenericLifecycleObserver(object);
    }

  一共分为5种类型,在这里我简单解释一下4和5类型的区别:

4和5类型的区别本质在于,我们定义的观察者对象是否支持生成一个新的类(可能是通过APT生成,具体我也不太清楚)。那么哪种类型的类支持生成,哪种不支持生成呢?其中,如果我们是直接new的一个匿名内部类对象,这种类型只能通过反射来调用,因为这种类没有名字,也就是getCanonicalName方法返回为null,例如我们是继承于LifecycleObserver定义一个新的非final的类,就支持生成新类,也就是走的是第4种类型。所以,从这里,我们得出一个结论,尽量不要通过new一个LifecycleObserver的匿名内部类对象来实现,因为反射会损耗性能。我们可以使用DefaultLifecycleObserver来达到我们的业务要求。

4. 添加Lifecycle的观察者

  到现在,我们已经了解到了LifecycleRegistry是将状态分发到每个LifecycleObserver。不过,之前的有些结论还没有得到一些证实,比如说:1. 为什么说每个观察者对象都以State从大到小放置在FastSafeIterableMap中?2. LifecycleObserver何时被包装在ObserverWithState呢?这些问题的答案都可以在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--;
    }

  在addObserver方法的最前面,我们就可以看到我们添加的LifecycleObserver对象就被包装成一个ObserverWithState对象。其次就是,通过FastSafeIterableMapputIfAbsent方法将ObserverWithState 对象存储起来,而通过State从大到的小排序就是通过这个方法实现:

    @Override
    public V putIfAbsent(@NonNull K key, @NonNull V v) {
        Entry<K, V> current = get(key);
        if (current != null) {
            return current.mValue;
        }
        mHashMap.put(key, put(key, v));
        return null;
    }
    protected Entry<K, V> put(@NonNull K key, @NonNull V v) {
        Entry<K, V> newEntry = new Entry<>(key, v);
        mSize++;
        if (mEnd == null) {
            mStart = newEntry;
            mEnd = mStart;
            return newEntry;
        }
        mEnd.mNext = newEntry;
        newEntry.mPrevious = mEnd;
        mEnd = newEntry;
        return newEntry;
    }

  FastSafeIterableMap的本质就是在Map中存储了一份,又在链表中存储了一份,而链表中的mStart表示头结点,mEnd表示尾节点。
  在addObserver方法其实还做一件事,就是状态的重放,也就是将Activity或者Fragment已经经历的状态都一一分发到新添加的观察者对象中去。这就能印证了我们之前说了,即使我们在onResume时机下添加观察者,onCreate和onStart也能正常回调。

5. Lifecycle其中的坑

  源码分析的差不多,最后我们再来介绍Lifecycle的坑吧

(1). 尽量不要通过new LifecycleObserver对象来监听生命周期

  这个在前面已经解释过了,这种实现方式的回调是通过反射来达到目的,反射对性能有所性能,我们在开发中要坚持一个原则:能不用反射就不要用反射

(2). 为什么Google爸爸要在ComponentActivityonSaveInstanceState方法做一个特殊处理?

  其实这个实现也是迫于无奈,Google爸爸这么做是为了处理一个边缘case。根据官方文档(使用生命周期感知型组件处理生命周期)的介绍,在onSaveInstanceState方法和onStop回调之间,存在一个时间间隙,在这个间隙里面可能会做更新UI的操作:比如说Fragment的attach,或者LiveData的更新进而更新UI。理论上当Activity回调了onSaveInstanceState方法,视图已经是处于不可见的状态了,不应该在更新UI了,包括LiveData此时也应该处于非活跃状态。但是由于在onStop方法里面才会分发状态,所以下游并不能知道此时不能更新UI。为了处理这种case,Google爸爸特意在onSaveInstanceState方法里面将状态分发下去。

6. 总结

  到这里,本文的内容也算是结束了,我在这里对本文做一个简单。

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