美文网首页Android开发Android开发经验谈
Android LifeCycle 源码学习总结

Android LifeCycle 源码学习总结

作者: 刨坑 | 来源:发表于2022-03-18 14:32 被阅读0次

    作者:入魔的冬瓜
    转载地址:https://juejin.cn/post/7075989487888629768

    整体设计

    Lifecycle的核心设计模式就是观察者模式。

    • LifeCycleOwner 是被观察者,LifecycleObserver 是观察者。

    • LifecycleRegistry 像是个中介,管理观察者和被观察者,处理来自LifeCycleOwner 的事件,进行状态同步,并通知所有的LifecycleObserver

    LifeCycle

    LifeCycle 的 State 和 Event

    先看看 LifecycleRegistry 的父类,Lifecycle 的一些定义。

    public abstract class Lifecycle {
    
        //添加Observer进来
        @MainThread
        public abstract void addObserver(@NonNull LifecycleObserver observer);
    
        //移除Observer
        @MainThread
        public abstract void removeObserver(@NonNull LifecycleObserver observer);
    
        //获取当前的State值
        @MainThread
        @NonNull
        public abstract State getCurrentState();
    
        //Event定义
        public enum Event {
            ON_CREATE,
            ON_START,
            ON_RESUME,
            ON_PAUSE,
            ON_STOP,
            ON_DESTROY,
            ON_ANY
        }
    
        //State值
        public enum State {
            DESTROYED,
            INITIALIZED,
            CREATED,
            STARTED,
            RESUMED;
    
            public boolean isAtLeast(@NonNull State state) {
                return compareTo(state) >= 0;
            }
        }
    }
    
    • 注意addObserver、removeObserver、getCurrentState这几个方法,都加上了@MainThread注解,所以在使用的过程中,尽量放在主线程进行调用,不然可能会引起一些崩溃问题。(多线程操作集合,可能引起 ArrayIndexOutOfBoundsException )
    • 事件驱动:LifecycleRegistry通过handleLifecycleEvent方法,接收外部发来的Event事件,修改内部的 State状态,并通知到所有的LifecycleObserver

    状态转换

    先看下 State 和 Event 的关系图,再看下相关的代码。

    1. 通过 getStateAfter 方法,可以根据Event,获取下一步的State值。
    2. 从左往右,称为状态上升。
    3. 从右往左,称为状态下降。
    4. upEvent,根据当前观察者的状态值,获取下一步的Event(状态上升过程中会用到,后面再讲)
        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);
        }
    
        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);
        }
    
        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;
                case RESUMED:
                    throw new IllegalArgumentException();
            }
            throw new IllegalArgumentException("Unexpected state value " + state);
        }
    

    状态大小

    因为State是枚举类型,并且枚举类型compareTo方法是根据每个枚举的ordinal值大小进行比较的,所以状态大小:DESTROYED < INITIALIZED < CREATED < STARTED < RESUMED

    用到的场景例子:

    LiveData#observe,默认只更新活跃状态的owner对象。(这里不过多分析LiveData的源码,只讲解一小部分逻辑)

    public void observe(@NonNull LifecycleOwner owner,Observer<? super T> observer);
    
    1. LiveData,会调用considerNotify会去通知相应的观察者。
    2. 使用shouldBeActive()判断当前owner的生命周期状态。如果当前 observer 对应的 owner 非活跃状态,直接return。
    3. LifecycleBoundObserver的 shouldBeActive,判断当前状态至少是 State.STARTED。
    4. 这就解释了当 Activity 处于后台,对应的状态是 State.STARTED ,那就不会收到LiveData的事件了。
       //LiveData
        private void considerNotify(ObserverWrapper observer) {
            if (!observer.mActive) {
                return;
            }
            //
            if (!observer.shouldBeActive()) {
                observer.activeStateChanged(false);
                return;
            }
            if (observer.mLastVersion >= mVersion) {
                return;
            }
            observer.mLastVersion = mVersion;
            observer.mObserver.onChanged((T) mData);
        }
    
        //LifecycleBoundObserver
            class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
    
            @Override
            boolean shouldBeActive() {
                return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
            }
    
            @Override
            public void onStateChanged(@NonNull LifecycleOwner source,
                    @NonNull Lifecycle.Event event) {
                if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                    removeObserver(mObserver);
                    return;
                }
                activeStateChanged(shouldBeActive());
            }
    
            @Override
            boolean isAttachedTo(LifecycleOwner owner) {
                return mOwner == owner;
            }
    
            @Override
            void detachObserver() {
                mOwner.getLifecycle().removeObserver(this);
            }
        }
    

    LifecycleRegistry

    LifecycleRegistry像是个中介,管理观察者和被观察者,处理事件分发和状态转换过程。

    绑定被观察者

    • 通过构造方法,传入LifecycleOwner,也就是被观察者。一般情况下,对应的就是 Activity 或者 Fragment。
    • 通过mLifecycleOwner弱引用Activity、Fragment。方便垃圾回收,也可以防止如果 LifeCycleRegistry 泄漏的情况下,导致对应的组件被进一步泄漏。
    • ok,这一步比较简单。这样的话,LifecycleRegistry就持有被被观察者了。
        private final WeakReference<LifecycleOwner> mLifecycleOwner;
    
        public LifecycleRegistry(@NonNull LifecycleOwner,也就是被观察者。一般情况下, 指的就是Activity或者Fragment。
        provider) {
            mLifecycleOwner = new WeakReference<>(provider);
            mState = INITIALIZED;
        }
    

    添加观察者

    LifecycleRegistry#addObserver

    FastSafeIterableMap
    • 所有的 Observer,最后会被保存到一个mObserverMap的集合里面
    • FastSafeIterableMap,本质上就是一个双向链表+HashMap的结构。(多搞一个HashMap,空间换时间,提高查询效率,解决链表遍历查询效率低的问题)
    • Map.Entry结构,包含前后节点的引用,自身的key、value值。
     private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap = new FastSafeIterableMap<>();
    
     public void addObserver(@NonNull LifecycleObserver observer) {
        ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
        if (previous != null) {
                return;
        }
        //省略代码
     }
    
    ObserverWithState
        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;
            }
        }
    
    • ObserverWithState,包装了原始的 LifecycleEventObserver(也就是 addObserver 里面的参数),通过dispatchEvent()通知状态变化,调用对应 Observer 的onStateChanged方法。
    • mState字段,保存当前 LifecycleObserver 的状态。为什么需要这个字段?
    1. 因为 LifeCycleRegistry 的状态与 LifecycleObserver 的状态不一定是一致的,需要不断将LifeCycleRegistry 的状态同步到每个 LifecycleObserver。
    2. 状态同步的过程是一步步的,并不是一次性直接修改state的值就行了,而是通过 dispatchEvent 一步步分发事件进行修改。
    3. 比如从 State.INITIALIZED 上升到 State.RESUMED 状态,LifecycleObserver 的 mState 会依次变成State.CREATED、STARTED,再变成 State.RESUME。(状态下降过程也是同个道理)
    例子

    场景举例:在Activity onResume的时候,添加一个新的LifecycleObserver。
    输出结果:这个新添加的 LifecycleEventObserver,onStateChanged 会依次收到Event.ON_CREATE、Event.ON_START、Event.ON_RESUME的事件。

       @Override
        protected void onResume() {
            super.onResume();
    
            getLifecycle().addObserver(new LifecycleEventObserver() {
                @Override
                public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
                    Log.d(TAG, "onStateChanged, event:"+event);
                }
            });
        }
    
    //日志输出
    onStateChanged, event:ON_CREATE
    onStateChanged, event:ON_START
    onStateChanged, event:ON_RESUME
    

    分析过程:

    1. 对于这个新添加的 LifecycleEventObserver,一开始ObserverWithState里面的mState值是INITIALIZED,但是 LifecycleRegistry 此时的 State 是 RESUME。
    2. 通过calculateTargetState方法计算得出,需要将 ObserverWithState 里面的 mState 也是要修改到RESUME这个状态。
    3. 再通过一个white循环,依次调用dispatchEvent方法分发ON_CREATE、ON_START、ON_RESUME给 ObserverWithState#mLifecycleObserver,修改 ObserverWithState 里面的 mState ,直到跟LifecycleRegistry 的 State 状态一致。
    4. 其实这就是状态上升的一个过程。

    事件分发与状态同步

    LifeCycleOwner通过调用handleLifecycleEvent方法,分发相应的生命周期事件给到LifeCycleRegistry,LifeCycleRegistry 根据事件,同步状态,并通知所有的观察者。

        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;
                return;
            }
            mHandlingEvent = true;
            sync();
            mHandlingEvent = false;
        }
    
        private void sync() {
            while (!isSynced()) {
                mNewEventOccurred = false;
                // 状态下降
                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;
        }
    
        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 forwardPass(LifecycleOwner lifecycleOwner) {
        Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
                mObserverMap.iteratorWithAdditions();
        while (ascendingIterator.hasNext() && !mNewEventOccurred) {
            Map.Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
            ObserverWithState observer = entry.getValue();
            while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
                    && mObserverMap.contains(entry.getKey()))) {
                pushParentState(observer.mState);
                final Event event = Event.upFrom(observer.mState);
                if (event == null) {
                    throw new IllegalStateException("no event up from " + observer.mState);
                }
                observer.dispatchEvent(lifecycleOwner, event);
                popParentState();
            }
        }
    }
    
    1. getStateAfter():根据 Event,获取下一个State值(也就是上面的那张状态装换图逻辑)
    2. moveToState():移动到当前的 State 状态。
    3. sync():同步状态,更新队列中所有 Observer 的状态,并调用所有观察者的onStateChanged
    4. isSynced():判断是否状态同步完成:队列头和队列尾的State与LifecycleRegistry的State一致,则说明状态同步过程结束。
    5. backwardPass():进行状态下降的一个过程。(从右往左)
    6. forwardPass():进行状态上升的一个过程。(从左往右)

    forwardPass 方法实现:
    第一层while循环,遍历队列里面的所有 Observer。
    第二层while循环,对每个 Observer 的mState进行一步步上升,并调用dispatchEvent进行通知,直接与 LifecycleRegistry 的 State 一致。

    LifeCycleOwner

    LifecycleOwner:被观察者,持有Lifecycle对象。Activity 和 Fragment 都实现了 LifecycleOwner ,标志着他们是具有生命周期的组件。

    生命周期事件分发实现

    • 对于 Activity 生命周期事件的分发,是通过一个ReportFragment进行处理的。ReportFragment是一个没有ui的 fragment
    • ComponentActivity#onCreate的时候,注入添加了一个ReportFragment。因为 Fragment 依赖于创建它的 Activity,所以 Fragment 的生命周期会和宿主 Activity 生命周期同步,这样就间接实现了监听 Activity 生命周期的功能。
    • 在 ReportFragment 相应的生命周期方法中,通过ReportFragment#dispatch方法,将 Activity 生命周期事件的分发给LifecycleRegistry
    • LifecycleRegistry 进行状态同步,并通知所有的 Observer。

    LifecyclerObserver

    观察者,可以监听对应LifecycleOnwer的生命周期变化。比较简单,不细讲了。
    讲一下在实际应用中,可能需要注意的问题。

    addObserver要放主线程

    //省略部分代码
    private ArrayList<State> mParentStates = new ArrayList<>();
    
    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;
        }
        State targetState = calculateTargetState(observer);
        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);
        }
    }
    
    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);
    }
    
    1. addObserver 新增观察者,会有一个状态同步的过程。中间用到mParentStates。
    2. mParentStates:这是一个通过popParentStatepushParentState更新的栈。主要是在状态同步过程中,执行订阅者的回调 dispatchEvent 前,先将订阅者当前状态 pushParentState 压入栈,在回调结束之后, popParentState 出栈
    3. mParentStates是个ArrayListArrayList不是线程安全的
    4. 所以如果有多个线程在同时执行addObserver这个过程,就可能引起崩溃。

    检测 addObserver 是否在主线程

    以 Activity 为例。

    1. 项目中一般会有个基类 Activity ,可以直接重写BaseActivity 的getLifecycle方法,返回一个新的LifecycleRegistry就行。
    2. 通过这个新的 LifecycleRegistry ,重写 addObserver方法,就可以拦截到所有监听 Activity 生命周期的Observer 了。
    3. 检测当前线程,是否是主线程。不是在主线程的话,可以打印相关的堆栈信息,提示开发者进行修改
    abstract class BaseActivity : AppCompatActivity() {
    
        //本地开发阶段,如果在非主线程addObserver的话,直接打个error日志或者throw exception,提示开发者进行修改
        var customLifeCycle: CustomLifeCycle? = null
    
        override fun getLifecycle(): Lifecycle? {
            if (DEBUG) {
                if (customLifeCycle == null) {
                    customLifeCycle = CustomLifeCycle(this)
                }
                return customLifeCycle
            }
            return super.getLifecycle()
        }
    }
    
    class CustomLifeCycle extends LifecycleRegistry {
    
        public CustomLifeCycle(@NonNull LifecycleOwner provider) {
            super(provider);
        }
    
        @Override
        public void addObserver(@NonNull LifecycleObserver observer) {
            //判断是否在主线程
            if (Looper.getMainLooper() != Looper.myLooper()){
                throw new IllegalStateException("addObserver need in main thread");
            }
            super.addObserver(observer);
        }
    }
    

    相关文章

      网友评论

        本文标题:Android LifeCycle 源码学习总结

        本文链接:https://www.haomeiwen.com/subject/cdwidrtx.html