“终于懂了~” 系列:Lifecycle

作者:g小志
转载地址:https://www.jianshu.com/u/70a8f4edb323

前言

Lifecycle生命周期感知型组件,用来执行、操作、响应另一个组件(如 Activity 和 Fragment)的生命周期状态的变化。

本文Lifecycle版本为2.2.0:

implementation ‘androidx.lifecycler:lifecycle-common:2.2.0’ //22.2.23 更新 2.5 ,2.2是用的比较多的版本

你真的了解Lifecycle了吗?

Lifecycle使用非常非常简单。默认你已经使用过Lifecycle。但如果我问你以下几个问题。你能回答出来几个?

  • Lifecycle的创建方式有几种?
  • 有什么不同?推荐使用哪种?为什么?
  • Event事件和State状态是什么关系
  • nStop()生命周期,处于什么State状态
  • Lifecycle是如何进行生命周期同步
  • 如果在onResume() 注册观察者会收到那几个种回调?为什么?
  • Activity/Fragment 实现Lifecycle能力的方式一样吗?
  • 为什么要这么设计?有什么好处?
  • Application能感知Activity生命周期吗?(如何使用Lifecycle监听前后台的能力)
  • Lifecycle从源码角度,简述Lifecycle的注册,派发,感知的过程
  • 什么嵌套事件?发生的时机?Lifecycle是如何解决的?

如果我是面试官,遇到简历上写掌握Jetpack组件,我一定是会问Lifecycle这几个问题。因为它首先是Jetpack另外两个超级核心组件ViewModel,LiveData,实现能力的基石。同时它的使用频率也非常高,看似简单,容易被忽略,但却很多东西值得学习。

这十几个问题,从用法到源码,从表面到延伸。如果全懂,说明你真正掌握了Lifecycle的80%,没错~!仅仅是8成。因为下面的源码分析,还会有更多延伸的问题。

Lifecycle基本使用

作为生命周期感知组件、它的作用就是监听宿主Activity/Fragment,然后派发给观察者。这句看似简单的概括,却倒出3个重要的角色:
宿主,观察者,用来派发的调度器

使用Lifecycle的方法很简单。

先创建Observer,可以直接继承父类LifecycleObserver。

public class LocationObserver implements LifecycleObserver {
    private static final String TAG = "LocationObserver";
    //1. 自定义的LifecycleObserver观察者,用注解声明每个方法观察的宿主的状态
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    void onCreate(@NotNull LifecycleOwner owner) {
        Timber.e("onCreate_ON_CREATE");
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    void onStart(@NotNull LifecycleOwner owner) {
        Timber.e("onStart_ON_START");
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    void onResume(@NotNull LifecycleOwner owner) {
        Timber.e("onResume_ON_RESUME");
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    void onPause(@NotNull LifecycleOwner owner) {
        Timber.e("onPause_ON_PAUSE");
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    void onStop(@NotNull LifecycleOwner owner) {
        Timber.e("onStop_ON_STOP");
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    void onDestroy(@NotNull LifecycleOwner owner) {
        Timber.e("onDestroy_ON_DESTROY");
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    void onAny(LifecycleOwner owner) {
        Timber.e("onAny_ON_ANY-->%s",owner.getLifecycle().getCurrentState());
    }
}

自己定义生命周期方法,并在每个方法上面标记对应生命周期的注解。同时还能获得LifecycleOwner也就是宿主Activity。

继承LifecycleEventObserver,复写onStateChanged方法。

public class EventObserver implements LifecycleEventObserver {

    @Override
    public void onStateChanged(@NonNull LifecycleOwner source,@NonNull Lifecycle.Event event) {
        switch (event) {
            case ON_CREATE:
                Timber.d("ON_CREATE");
                break;
            case ON_START:
                Timber.d("ON_START");
                break;
            case ON_RESUME:
                Timber.d("ON_RESUME");
                break;
            case ON_PAUSE:
                Timber.d("ON_PAUSE");
                break;
            case ON_STOP:
                Timber.d("ON_STOP");
                break;
            case ON_DESTROY:
                Timber.d("ON_DESTROY");
                break;
            default:
                break;
        }
    }
}

继承FullLifecycleObserver,直接复写对应的生命周期回调。

public class FullLocationObserver implements DefaultLifecycleObserver {
    @Override
    public void onCreate(@NonNull LifecycleOwner owner) {
        Timber.e("onCreate");
    }
    @Override
    public void onStart(@NonNull LifecycleOwner owner) {
        Timber.e("onStart");
    }
    @Override
    public void onResume(@NonNull LifecycleOwner owner) {
        Timber.e("onResume");
    }
    @Override
    public void onPause(@NonNull LifecycleOwner owner) {
        Timber.e("onPause");
    }
    @Override
    public void onStop(@NonNull LifecycleOwner owner) {
        Timber.e("onStop");
    }
    @Override
    public void onDestroy(@NonNull LifecycleOwner owner) {
        Timber.e("onDestroy");
    }
}

此时你会发现,你无法直接继承FullLifecycleObserver这时你要添加一个依赖:

implementation ‘androidx.lifecycler:lifecycle-common:2.2.0’
替换上面引入的依赖(默认会集成上面的)
implementation “androidx.lifecycle:lifecycle-common-java8:2.2.0”

继承DefaultLifecycleObserver,它是FullLifecycleObserver的子类,因为在Java8以后,支持interface接口类型,可以有自己的默认实现。然后在Activity#OnCreate()中调用如下方法:

lifecycle.addObserver(LocationObserver())

接着,你就可以使用Lifecycle的能力了。

从源码了解过程

如果是MVP,你可以让你的Presenter去实现Observer,在处理逻辑时获得感知的能力。但如果我们把注册的代码lifecycle.addObserver(LocationObserver())放入onResume()方法中,会发生什么?你会发现Observer除了可以收到onResume事件,竟然还可以收到onCreate,onStart。也就说宿主的状态,会同步给观察者。这是怎么做到的?

感知监听

getLifecycle点进去,会进入到ComponentActivity核心代码。

public class ComponentActivity extends Activity implements LifecycleOwner{
  private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
   @NonNull
   @Override
   public Lifecycle getLifecycle() {
      return mLifecycleRegistry;
   }

  protected void onCreate(Bundle bundle) {
      super.onCreate(savedInstanceState);
      //往Activity上添加一个fragment,用以报告生命周期的变化
      //目的是为了兼顾不是继承自AppCompactActivity的场景.
      ReportFragment.injectIfNeededIn(this); 
}
  1. LifecycleRegistry是Lifecycle的子类,通过new LifecycleRegistry(this)把宿主Owner,也就是当前Activity作为构造参数传递进去
  2. Activity并不是直接派发生命周期,而是利用ReportFragment.injectIfNeededIn(this),
public class ReportFragment extends Fragment{
  public static void injectIfNeededIn(Activity activity) {
        android.app.FragmentManager manager = activity.getFragmentManager();
        if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
            manager.beginTransaction().add(new ReportFragment(),REPORT_FRAGMENT_TAG).commit();
            manager.executePendingTransactions();
        }
  }

    @Override
    public void onStart() {
        super.onStart();
        dispatch(Lifecycle.Event.ON_START);
    }
    @Override
    public void onResume() {
        super.onResume();
        dispatch(Lifecycle.Event.ON_RESUME);
    }
    @Override
    public void onPause() {
        super.onPause();
        dispatch(Lifecycle.Event.ON_PAUSE);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        dispatch(Lifecycle.Event.ON_DESTROY);
    }
    private void dispatch(Lifecycle.Event event) {
         //调用宿主的Lifecycle 
         Lifecycle lifecycle = activity.getLifecycle();
         if (lifecycle instanceof LifecycleRegistry) {
             ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
         }
}

ReportFragment.injectIfNeededIn(this)的作用是在Activity之上,创建一个不可见的Fragment的。当Fragment的生命周期发生变化,会通过dispatch(),接着调用((LifecycleRegistry) lifecycle).handleLifecycleEvent(event)来分发事件。这样做的目的是为了当页面不是继承ComponentActivity,而是直接继承Activity,那么它就没有了感知的能力。此时需要自己实现LifecycleOwner,复写getLifecycle(),然后将自己传入进new LifecycleRegistry(this),就可以成为宿主,让其他Observer来监听。ReportFragment.injectIfNeededIn(this)另一个使用的地方LifecycleDispatcher。

class LifecycleDispatcher {

    private static AtomicBoolean sInitialized = new AtomicBoolean(false);

    static void init(Context context) {
        if (sInitialized.getAndSet(true)) {
            return;
        }
        ((Application) context.getApplicationContext())
                .registerActivityLifecycleCallbacks(new DispatcherActivityCallback());
    }

    @SuppressWarnings("WeakerAccess")
    @VisibleForTesting
    static class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks {

        @Override
        public void onActivityCreated(Activity activity,Bundle savedInstanceState) {
            ReportFragment.injectIfNeededIn(activity);
        }

        @Override
        public void onActivityStopped(Activity activity) {
        }

        @Override
        public void onActivitySaveInstanceState(Activity activity,Bundle outState) {
        }
    }

    private LifecycleDispatcher() {

直接为Activity注入ReportFragment,使得每个页面都能成为宿主,让观察者感知。当然,你里面要自己实现LifecycleOwner,复写getLifecycle(),然后将自己传入进new LifecycleRegistry(this)。这部分与Lifecycle关系不大,只是作为知识扩展

总结

  1. 监听过程就是Activity/Fragment继承LifecycleOwner,并在子类CommponentActivity中创建Lifecycle的子类LifecycleRegistry。在复写getLifecycle()的方法中将子类LifecycleRegistry返回。
  2. 在onCreate()中注入ReportFragment,在生命周期回调后,通过getLifecycle()的方法得到LifecycleRegistry对象中的handleLifecycleEvent(event)方法给每个观察者派发生命周期事件。

为什么以Activity为例子,而不是像其他文章,以Fragement为例子,是因为你去看眼源码就会发现ReportFragment类中的dispatch()过程和Fragement如出一辙:

ublic class Fragment implements xxx,LifecycleOwner {
    //...
    void performCreate(Bundle savedInstanceState) {
        onCreate(savedInstanceState);  //1.先执行生命周期方法
        //...省略代码
        //2.生命周期事件分发
        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() {
        //3.注意,调用顺序变了
        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();
    }
}

参照《Android 架构组件(一)——Lifecycle》一文:

https://blog.csdn.net/zhuzp_blog/article/details/78871374?spm=1001.2014.3001.5501

文中的时序图:

同时,你会发现Fragment中performCreate()、performStart()、performResume()会先调用自身的onXXX()方法,然后再调用LifecycleRegistry的handleLifecycleEvent()方法;而在performPause()、performStop()、performDestroy()中会先LifecycleRegistry的handleLifecycleEvent()方法,然后调用自身的onXXX()方法。

同步

上面是监听过程,getLifecycle().addObserver(LocationObserver())注册代码的前半部分。现在我们获得感知宿主的能力,并将事件event转发给LifecycleRegistry,他是整个流程的核心。现在来看后半部分,如何注册Observer后可以在任何时机(onDestory除外),感知完整生命周期。

不过在此之前,我们要先搞懂什么是状态State和事件Event。

public abstract class Lifecycle {
    @MainThread
    public abstract void addObserver(@NonNull LifecycleObserver observer);
     @MainThread
    public abstract void removeObserver(@NonNull LifecycleObserver observer);
    @MainThread
    @NonNull
    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,/**
         *     <li>after {@link android.app.Activity#onStart() onStart} call;
         *     <li><b>right before</b> {@link android.app..Activity#onPause( onPause} call.
         * </ul>
         */
        STARTED,RESUMED;
        public boolean isAtLeast(@NonNull State state) {
            return compareTo(state) >= 0;
        }
    }
}

在Lifecycle类中除了add,remove外,还有两个枚举类,Event事件对应的就是Activty的onCreate,onStart()事件,而状态却只有5种。以STARTED状态为例,这个状态发生在Activity#onStart()之后,Activity#onPause()之前。什么意思呢?请看下面这张图:

这张图我们一定见过,但这次我们横着对半切一刀,上面表示生命周期的前进,下面表示生命周期的后退,一定要记住,这对我们后的理解源码非常重要,接着我们在解释下:

Activity刚刚创建的时候它一定是INITIALIZED状态,执行onCreate()方法后,进入到CREATED状态,执行onStart()方法后,进入到STARTED状态,执行onResume()方法后,进入到RESUMED状态,这个过程就表示生命周期的前进。

**当我们跳转下一个Activity后,执行onPase()方法后,又重新回到STARTED状态,执行onStop()方法后,进入到CREATED状态,最后执行onDestory()方法后,进入到DESTROYED状态。这个过程表示生命周期的后退。**参照《Android 架构组件(一)——Lifecycle》一文:

https://blog.csdn.net/zhuzp_blog/article/details/78871374?spm=1001.2014.3001.5501

文中的关系图:

这个图片仅作参考,ObserverWithState类中的关系有所变换,mLifeCycleObserver->LifeCycleEventObserver。LifecycleRegistryshi生命周期注册,记录,派发事件的地方,理解状态和事件的关系,对我们搞清楚LifecycleRegistry非常有帮助,下面以在onResume()中调用lifecycle.addObserver(LocationObserver())为例:

public LifecycleRegistry(@NonNull LifecycleOwner provider) {
        mLifecycleOwner = new WeakReference<>(provider);
        mState = INITIALIZED;
    }

    public void addObserver(@NonNull LifecycleObserver observer) {
        //1
        State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
        //2
        ObserverWithState statefulObserver = new ObserverWithState(observer,initialState);
        //3
        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;
        //4
        State targetState = calculateTargetState(observer);
        mAddingObserverCounter++;
        while ((statefulObserver.mState.compareTo(targetState) < 0
                && mObserverMap.contains(observer))) {
            pushParentState(statefulObserver.mState);
            //5
            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`
    static class ObserverWithState {
        State mState;
        LifecycleEventObserver mLifecycleObserver;

        ObserverWithState(LifecycleObserver observer,State initialState) {
            mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
            mState = initialState;
        }

        void dispatchEvent(LifecycleOwner owner,Event event) {
            State newState = getStateAfter(event);
            mState = min(mState,newState);
            mLifecycleObserver.onStateChanged(owner,event);
            mState = newState;
        }
    }
    private State calculateTargetState(LifecycleObserver observer) {
        Entry<LifecycleObserver,ObserverWithState> previous = mObserverMap.ceil(observer);

        State siblingState = previous != null ? previous.getValue().mState : null;
        State parentState = !mParentStates.isEmpty() ? mParentStates.get(mParentStates.size() - 1)
                : null;
        return min(min(mState,siblingState),parentState);
    }

    private static Event upEvent(State state) {
        switch (state) {
            case INITIALIZED:
            case DESTROYED:
                return ON_CREATE;
            case CREATED:
                return ON_START;
            case STARTED:
                return ON_RESUME;
                //发生生命周期的前进,RESUMED处于前进阶段的末尾,无法前进了。因为之后要发生生命周期后退
                //所以抛出异常
            case RESUMED:
                throw new IllegalArgumentException();
        }
        throw new IllegalArgumentException("Unexpected state value " + state);
    }
    //根据事件,判断所处的状态
    static State getStateAfter(Event event) {
        switch (event) {
            case ON_CREATE:
            case ON_STOP:
                return CREATED;
            case ON_START:
            case ON_PAUSE:
                return STARTED;
            case ON_RESUME:
                return RESUMED;
            case ON_DESTROY:
                return DESTROYED;
            case ON_ANY:
                break;
        }
        throw new IllegalArgumentException("Unexpected event value " + event);
    }
  1. mState表示宿主的状态或是Observer应该处于正确的状态,如果不是DESTROYED,那么就赋值为INITIALIZED状态,什么意思?就是当你添加一个Observer的时机是在onDestory()那么直接设置为DESTROYED,之后便不会给这个观察者派发事件,否则即便你是在onReume()注册,都是INITIALIZED,为什么要这样做,而不是直接派发RESUMED。这就是LifecycleRegistry的高明之处,因为他下面要做事件同步。如果直接派发RESUMED,观察者且不是丢失了ON_CREATE,ON_START事件?这与Lifecycycle设计的初衷肯定是不相符的
  2. 将observer和initialState,封装进ObserverWithState,从类名可以看出,他是持有观察者和它当前状态的包装类
  3. 观察者Observer为key,ObserverWithState为Value封装进Map,mObserverMap这个存储集合它的作用没啥可说的,但它的数据结构很特别,可以理解为是一个链表结构的Map,记录了链头Start和链未End,同时每个Value元素,还记录了当前值的Next和Previous。
  4. calculateTargetState翻译为计算目标状态,也就是计算传入的Observer应该是什么状态。而它里面计算的逻辑很有意思。展开说涉及到嵌套事件下面再讲,简单来说就是根据集合中的前一个Observer状态和宿主的状态与当前Observer应该处于正确的状态mState作min()比较。从这里我们可以得出一个Activity/Fragment可以有多个观察者,每个观察者的状态全部一致
  5. 循环判断,如果观察者状态小于目标状态,表示发生生命周期的前进。调用upEvent(State state)计算前进事件。初始化是INITIALIZED状态,发生前进事件,根据前面的图,应该发生ON_CREATE事件。这有点不好理解。就是小于的情况下。肯定发生生命周期的前进,所以INITIALIZED状态下,下一个事件必然是ON_CREATE事件。然后调用ObserverWithState#dispatchEvent(),通过 getStateAfter(event)来根据事件,判断所处的状态。ON_CREATE事件一定是CREATED状态。接着保存起来newState,调用注册进来的观察者的回调方法mLifecycleObserver.onStateChanged(owner,event)把事件分发出去,然后更新mStatemState = newState
  6. 下次循环mState=CREATED还是小于目标状态,upEvent():CREATED–>ON_START,getStateAfter(event):ON_START–>STARTED,保存状态newState,回调监听onStateChanged,保存状态mState = newState,直到mState = RESUMED

经过循环之后。新注册的Observer和宿主同步到相同的生命周期。

派发

当宿主生命周期发生变化,会调用mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)来向观察者派发,直接看分析然后再结合源码。

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

    private void moveToState(State next) {
        mState = next;
        sync();//2
    }

    private void sync() {
        while (!isSynced()) {//3
        //当宿主状态小于 最早添加进来的观察者,为什么是最早,首先集合中的观察者是按顺序添加的,State应该是一致的,小于最早观察者,一定小于后面最后观察者
            if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
                backwardPass(lifecycleOwner);//4
            }
            Entry<LifecycleObserver,ObserverWithState> newest = mObserverMap.newest();
            if (!mNewEventOccurred && newest != null
                    //当宿主状态大于最新的道理相同
                    && mState.compareTo(newest.getValue().mState) > 0) {
                forwardPass(lifecycleOwner);//5
            }
        }
    }

    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;
    }

    private void backwardPass(LifecycleOwner lifecycleOwner) {
            while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
                    && mObserverMap.contains(entry.getKey()))) {
                Event event = downEvent(observer.mState);
                observer.dispatchEvent(lifecycleOwner,event);
            }
    }   

    private void forwardPass(LifecycleOwner lifecycleOwner) {
            while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
                    && mObserverMap.contains(entry.getKey()))) {
                observer.dispatchEvent(lifecycleOwner,upEvent(observer.mState));
            }
    }       
    private static Event downEvent(State state) {
        switch (state) {
        //最初的状态 无法再后退
            case INITIALIZED:
                throw new IllegalArgumentException();
            case CREATED:
                return ON_DESTROY;
            case STARTED:
                return ON_STOP;
            case RESUMED:
                return ON_PAUSE;
                //最末的状态 无法再回退
            case DESTROYED:
                throw new IllegalArgumentException();
        }
        throw new IllegalArgumentException("Unexpected state value " + state);
    } 
  1. 根据传入的事件event,判断宿主的状态
  2. 进行复制mState = next,然后调用sync()开始同步所有观察者
  3. isSynced()是否已经同步过了,取出Map中首尾元素,两者相等同时尾部元素,也就是最后添加,最新的元素和宿主状态mState相同,就说明同步过了不用同步。再次印证一个Activity/Fragment可以有多个观察者,每个观察者的状态全部一致,但注意sync()中是取的非while (!isSynced())所以不一致时进入接下来的循环
  4. if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) ,宿主状态小于观察者的状态,这是什么情况?如果你看懂前面的表,这里就不难理解,举个例子:观察者为RESUMED状态,此时宿主发生onPase()生命周期,那么宿主会进入STARTED状态。进入生命周期后退过程所以会调用backwardPass(lifecycleOwner)向后传递
  5. (observer.mState.compareTo(mState) > 0 上面判断是宿主小于观察者,backwardPass判断观察者大于宿主,完全是一个意思,接着会调用downEvent,根据状态回退RESUMED–>ON_PAUSE
  6. observer.dispatchEvent(lifecycleOwner,event)更新状态,分发观察者事件,更新mState
  7. mState.compareTo(newest.getValue().mState) > 0 事件前进forwardPass(lifecycleOwner)与之前同步过程完全相同

统一Observer
思考一个问题
ObserverWithState#dispatch是给观察者分发事件的位置,但他调用的是onStateChange(),但我们回调方式的实现,是完全不同的,他是如何做到统一的呢?

    static class ObserverWithState {
        State mState;
        LifecycleEventObserver mLifecycleObserver;

        ObserverWithState(LifecycleObserver observer,event);
            mState = newState;
        }
    }

mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer)答案就是适配器模式,看就在这里。

 @NonNull
    static LifecycleEventObserver lifecycleEventObserver(Object object) {//Object 就是传入的observer
        boolean isLifecycleEventObserver = object instanceof LifecycleEventObserver;
        boolean isFullLifecycleObserver = object instanceof FullLifecycleObserver;
        if (isLifecycleEventObserver && isFullLifecycleObserver) {
            return new FullLifecycleObserverAdapter((FullLifecycleObserver) object,(LifecycleEventObserver) object);
        }
        if (isFullLifecycleObserver) {
            return new FullLifecycleObserverAdapter((FullLifecycleObserver) object,null);
        }

        if (isLifecycleEventObserver) {
            return (LifecycleEventObserver) object;
        }

        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);
    }
  • Object 就是传入的observer,如果是如果同时实现LifecycleEventObserver,FullLifecycleObserver,创建FullLifecycleObserverAdapter
  • 如果是isFullLifecycleObserver,创建FullLifecycleObserverAdapter
  • 如果是isLifecycleEventObserver,直接返回

而FullLifecycleObserverAdapter ,所有适配器Adapter都是继承自LifecycleEventObserver。这样就可以收拢统一后调用。而直接继承LifecycleObserver又是怎么判断的呢?

int type = getObserverConstructorType(klass);  

最终调用  
 /**
     * Create a name for an adapter class.
     */
    public static String getAdapterName(String className) {
        return className.replace(".","_") + "_LifecycleAdapter";
    }

当引入androidx.lifecycle:lifecycle-compiler:2.2.0会利用APT,运行时注解处理器生成工具类并拼接类名MyObserver_LifecycleAdapter,然后调取注解标记的观察者,否者会用ReflectiveGenericLifecycleObserver,反射执行。嵌套事件这部分不好理解,目前个人的理解就是,先弄清楚什么时候回出现嵌套事件,两种情况:

  1. 在新添加观察者时,同步还未完成,此时宿主又发生了生命周期变化,那么此时就会导致不同步的问题
  2. 在派发生命周期给观察者时,又有新的观察者添加进来,那么新的观察者可能和其他观察者状态不同步的问题。

嵌套事件,说白了就是同步冲突。因为所有观察者和宿主的状态是完全相同的,一旦生命周期派发,或是新的观察者添加进来时,如果生命周期或观察者集合元素发生变化,就可能会导致不同步。这错乱不是来自多线程。因为细心的你会发现。LifeCycleRegistry的大部分方法都标注@MainThread注解。也就说,冲突并非是多线程,而是上面两种情况。

那么LifeCycleRegistry又是如何如何处理的呢?答案是利用多个标记位表示状态,同时将新添加的观察者,或是正在变化的观察者压入栈。正确同步后后再出栈,也就是mParentStates这个mParentStates类型的集合。所以一旦出现观察者状态不一致导致无法正常出栈。这个栈mParentStates内的元素就不是空。就需要来重新处理或者判断。核心思想大概是这样样子。就是多个标记位和栈管理,来确保状态的同步和一致。

以上是个人理解。对嵌套事件感兴趣,想深入理解,可以看这篇:

https://blog.csdn.net/quiet_olivier/article/details/103384146?spm=1001.2014.3001.5502

总结

LifeCycle组件简单,深入却有很复杂,理解后又会发现很有意思。但大部分文章却无法做到既深入,又能体现却他人的不同。更无法完全解答开头的十几个问题。不过现在你应该有了自己的答案。

原文地址:https://blog.csdn.net/weixin_61845324

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


更新Android SDK到3.0版本时,遇到Failed to rename directory E:\android\tools to E:\android\temp\ToolPackage.old01问题,导致无法更新,出现该问题的原因是由于3.0版本与较早的sdk版本之间文件结构有冲突,解决
Android 如何解决dialog弹出时无法捕捉Activity的back事件 在一些情况下,我们需要捕捉back键事件,然后在捕捉到的事件里写入我们需要进行的处理,通常可以采用下面三种办法捕捉到back事件: 1)重写onKeyDown或者onKeyUp方法 2)重写onBackPressed方
Android实现自定义带文字和图片的Button 在Android开发中经常会需要用到带文字和图片的button,下面来讲解一下常用的实现办法。一.用系统自带的Button实现 最简单的一种办法就是利用系统自带的Button来实现,这种方式代码量最小。在Button的属性中有一个是drawable
Android中的&quot;Unable to start activity ComponentInfo&quot;的错误 最近在做一款音乐播放器的时候,然后在调试的过程中发现一直报这个错误&quot;Unable to start activity ComponentInfo&quot;,从字面
Android 关于长按back键退出应用程序的实现最近在做一个Android上的应用,碰到一个问题就是如何实现长按back键退出应用程序。在网上查找了很多资料,发现几乎没有这样的实现,大部分在处理时是双击back键来退出应用程序。参考了一下双击back键退出应用程序的代码,网上主流的一种方法是下面
android自带的时间选择器只能精确到分,但是对于某些应用要求选择的时间精确到秒级,此时只有自定义去实现这样的时间选择器了。下面介绍一个可以精确到秒级的时间选择器。 先上效果图: 下面是工程目录: 这个控件我也是用的别人的,好像是一个老外写的,com.wheel中的WheelView是滑动控件的主
Android平台下利用zxing实现二维码开发 现在走在大街小巷都能看到二维码,而且最近由于项目需要,所以研究了下二维码开发的东西,开源的二维码扫描库主要有zxing和zbar,zbar在iPos平台上应用比较成熟,而在Android平台上主流还是用zxing库,因此这里主要讲述如何利用zxing
Android ListView的item背景色设置以及item点击无响应等相关问题 在Android开发中,listview控件是非常常用的控件,在大多数情况下,大家都会改掉listview的item默认的外观,下面讲解以下在使用listview时最常见的几个问题。1.如何改变item的背景色和按
如何向Android模拟器中导入含有中文名称的文件在进行Android开发的时候,如果需要向Android模拟器中导入文件进行测试,通过DDMS下手动导入或者在命令行下通过adb push命令是无法导入含有中文文件名的文件的。后来发现借用其他工具可以向模拟器中导入中文名称的文件,这个工具就是Ultr
Windows 下搭建Android开发环境一.下载并安装JDK版本要求JDK1.6+,下载JDK成功后进行安装,安装好后进行环境变量的配置【我的电脑】-——&gt;【属性】——&gt;【高级】 ——&gt;【环境变量】——&gt;【系统变量】中点击【新建】:变量名:CLASSPATH变量值:……
如何利用PopupWindow实现弹出菜单并解决焦点获取以及与软键盘冲突问题 在android中有时候可能要实现一个底部弹出菜单,此时可以考虑用PopupWindow来实现。下面就来介绍一下如何使用PopupWindow实现一个弹出窗。 主Activity代码:public void onCreat
解决Android中的ERROR: the user data image is used by another emulator. aborting的方法 今天调试代码的时候,突然出现这个错误,折腾了很久没有解决。最后在google上找到了大家给出的两种解决方案,下面给出这两种方法的链接博客:ht
AdvserView.java package com.earen.viewflipper; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory;
ImageView的scaleType的属性有好几种,分别是matrix(默认)、center、centerCrop、centerInside、fitCenter、fitEnd、fitStart、fitXY。 |值|说明| |:--:|:--| |center|保持原图的大小,显示在ImageVie
文章浏览阅读8.8k次,点赞9次,收藏20次。本文操作环境:win10/Android studio 3.21.环境配置 在SDK Tools里选择 CMAKE/LLDB/NDK点击OK 安装这些插件. 2.创建CMakeLists.txt文件 在Project 目录下,右键app,点击新建File文件,命名为CMakeLists.txt点击OK,创建完毕! 3.配置文件 在CMa..._link c++ project with gradle
文章浏览阅读1.2w次,点赞15次,收藏69次。实现目的:由mainActivity界面跳转到otherActivity界面1.写好两个layout文件,activity_main.xml和otherxml.xmlactivity_main.xml&lt;?xml version="1.0" encoding="utf-8"?&gt;&lt;RelativeLayout ="http://schemas..._android studio 界面跳转
文章浏览阅读3.8w次。前言:最近在找Android上的全局代理软件来用,然后发现了这两款神作,都是外国的软件,而且都是开源的软件,因此把源码下载了下来,给有需要研究代理这方面的童鞋看看。不得不说,国外的开源精神十分浓,大家相互使用当前基础的开源软件,然后组合成一个更大更强的大开源软件。好吧,废话不多说,下面简单介绍一下这两款开源项目。一、ProxyDroid:ProxyDroid功能比较强大,用到的技术也比较多,源码也_proxydroid
文章浏览阅读2.5w次,点赞17次,收藏6次。创建项目后,运行项目时Gradle Build 窗口却显示错误:程序包R不存在通常情况下是不会出现这个错误的。我是怎么遇到这个错误的呢?第一次创建项目,company Domain我使用的是:aven.com,但是创建过程在卡在了Building 'Calculator' Gradle Project info这个过程中,于是我选择了“Cancel”第二次创建项目,我还是使用相同的项目名称和项目路_r不存在
文章浏览阅读8.9w次,点赞4次,收藏43次。前言:在Android上使用系统自带的代理,限制灰常大,仅支持系统自带的浏览器。这样像QQ、飞信、微博等这些单独的App都不能使用系统的代理。如何让所有软件都能正常代理呢?ProxyDroid这个软件能帮你解决!使用方法及步骤如下:一、推荐从Google Play下载ProxyDroid,目前最新版本是v2.6.6。二、对ProxyDroid进行配置(基本配置:) (1) Auto S_proxydroid使用教程
文章浏览阅读1.1w次,点赞4次,收藏17次。Android Studio提供了一个很实用的工具Android设备监视器(Android device monitor),该监视器中最常用的一个工具就是DDMS(Dalvik Debug Monitor Service),是 Android 开发环境中的Dalvik虚拟机调试监控服务。可以进行的操作有:为测试设备截屏,查看特定进程中正在运行的线程以及堆栈信息、Logcat、广播状态信息、模拟电话_安卓摄像头调试工具