Android LifeCycle 源码学习总结

整体设计

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 的关系图,再看下相关的代码。

image.png

  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值。

image.png

 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 一致。

image.png

LifeCycleOwner

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

image.png

生命周期事件分发实现

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

image.png

image.png

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);
    }
}
复制代码

Guess you like

Origin juejin.im/post/7075989487888629768