Lifecycle原理

159 阅读7分钟

1. 介绍

Lifecycle 是 Jetpack 中的一个生命周期感知组件,基于观察者模式来感知 ActivityFragment 生命周期状态的变化。

Lifecycle 组件中,抽象类 Lifecycle 使用两个枚举来跟踪其关联组件的生命周期状态,分别是 EventState

/**
 * Event 对应着 Activity 和 Fragment 的生命周期
 */
public enum Event {
    ON_CREATE,
    ON_START,
    ON_RESUME,
    ON_PAUSE,
    ON_STOP,
    ON_DESTROY,
    ON_ANY
}

/**
 * State 用来记录当前关联的 Activity 或 Fragment 处于什么状态
 */
public enum State {
    // 销毁状态
    DESTROYED,
    // 初始化状态
    INITIALIZED,
    // 创建但不可见状态
    CREATED,
    // 可见但未获取焦点状态
    STARTED,
    // 获取焦点状态
    RESUMED
}

Lifecycle 组件的实现原理是:当 ActivityFragment 生命周期变化时,被观察者通知观察者 EventState 的变化,观察者根据这些变化来执行相应的操作。

因此,要了解 Lifecycle 内部原理,需要解答以下问题:

  1. 观察者和被观察者分别是谁?
  2. 观察者和被观察者如何关联?
  3. 被观察者如何感知 ActivityFragment 生命周期状态的变化?
  4. 被观察者如何通知观察者生命周期状态的变化?

2. Lifecycle 中的观察者和被观察者

抽象观察者 LifecycleObserver

LifecycleObserver 是一个空接口,表示可以感知生命周期变化的观察者:

public interface LifecycleObserver {
    // 空接口
}

具体观察者

具体的观察者需要实现 LifecycleEventObserver 接口,定义在生命周期变化时的具体行为:

public interface LifecycleEventObserver extends LifecycleObserver {
    void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}

class MyLifecycleObserver implements LifecycleEventObserver {
    @Override
    public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
        switch (event) {
            case ON_CREATE:
                // 创建时的操作
                break;
            case ON_START:
                // 可见时的操作
                break;
            case ON_RESUME:
                // 获取焦点时的操作
                break;
            case ON_PAUSE:
                // 失去焦点时的操作
                break;
            case ON_STOP:
                // 不可见时的操作
                break;
            case ON_DESTROY:
                // 销毁时的操作
                break;
        }
    }
}

抽象被观察者 Lifecycle

Lifecycle 作为被观察者,定义了添加和移除观察者的方法:

public abstract class Lifecycle {
    public abstract void addObserver(@NonNull LifecycleObserver observer);
    public abstract void removeObserver(@NonNull LifecycleObserver observer);
}

具体被观察者 LifecycleRegistry

LifecycleRegistry 实现了 Lifecycle 接口,管理生命周期事件并通知观察者:

3. 添加和移除观察者

ActivityFragment 中,我们可以通过 getLifecycle() 方法获取 Lifecycle 对象,并添加 LifecycleObserver

示例代码

class MyLifecycleActivity : AppCompatActivity() {

    private lateinit var myLifecycleObserver: MyLifecycleObserver

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        myLifecycleObserver = MyLifecycleObserver()
        lifecycle.addObserver(myLifecycleObserver)
    }
}

源码分析

上面代码中的 lifecycle 就是 LifecycleRegistry 对象。LifecycleRegistry 源码如下:

public class LifecycleRegistry extends Lifecycle {

    private final SafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap = new SafeIterableMap<>();
    private State mState;

    /**
     * 添加观察者
     * @param observer 观察者对象
     */
    @Override
    public void addObserver(@NonNull LifecycleObserver observer) {
        // 检查是否在主线程
        enforceMainThreadIfNeeded("addObserver");
        // 初始化状态
        State initialState = mState == State.DESTROYED ? State.DESTROYED : State.INITIALIZED;
        // 创建 LifecycleObserver 的包装类 ObserverWithState
        ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
        // 将 LifecycleObserver 添加到 map 中
        ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
        if (previous == null && mState != State.INITIALIZED) {
            // 调用 observer 的 onStateChanged 方法通知当前状态
            statefulObserver.dispatchEvent(mLifecycleOwner, upEvent(mState));
        }
    }

    @Override
    public void removeObserver(@NonNull LifecycleObserver observer) {
        enforceMainThreadIfNeeded("removeObserver");
        // 将 LifecycleObserver 从 map 中移除
        mObserverMap.remove(observer);
    }
}

LifecycleRegistry 在添加观察者时,会检查当前的状态并立即通知新添加的观察者,使其与当前的生命周期状态同步。

4. Lifecycle 如何观察 Activity 的生命周期状态变化

Lifecycle 依赖于 LifecycleOwner 接口,ActivityFragment 都实现了该接口。LifecycleOwner 提供了 getLifecycle 方法,用于获取 Lifecycle 实例:

public interface LifecycleOwner {
    @NonNull
    Lifecycle getLifecycle();
}

public class ComponentActivity extends AppCompatActivity implements LifecycleOwner {
    // 创建被观察者对象 LifecycleRegistry
    private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

    /**
     * 实现 LifecycleOwner 的 getLifecycle 方法
     * 返回创建的 LifecycleRegistry 对象
     */
    @NonNull
    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 将 mLifecycleRegistry 感知生命周期的任务交给 ReportFragment
        ReportFragment.injectIfNeededIn(this);
    }
}

ComponentActivity 中,实现了 LifecycleOwner 接口,并且在 getLifecycle 方法中返回创建的 LifecycleRegistry 对象。生命周期的感知任务被交给了 ReportFragment 处理。

ReportFragment 如何处理生命周期事件

public class ReportFragment extends Fragment {

    // 通过 FragmentManager 添加 ReportFragment
    public static void injectIfNeededIn(Activity activity) {
        if (Build.VERSION.SDK_INT >= 29) {
            ReportFragment.LifecycleCallbacks.registerIn(activity);
        } else {
            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 onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        dispatch(Lifecycle.Event.ON_CREATE);
    }

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

    // ...省略其它生命周期方法

    @Override
    public void onDestroy() {
        super.onDestroy();
        dispatch(Lifecycle.Event.ON_DESTROY);
    }

    private void dispatch(@NonNull Lifecycle.Event event) {
        if (Build.VERSION.SDK_INT < 29) {
            // 仅在 API 29 之前通过 ReportFragment 分发事件
            dispatch(getActivity(), event);
        }
    }

    /**
     * 将生命周期变化分发给 LifecycleRegistry
     */
    static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
        // 如果 Activity 实现了 LifecycleOwner 接口
        if (activity instanceof LifecycleOwner) {
            // 通过 LifecycleOwner 的 getLifecycle 获取 lifecycle 对象
            Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
            if (lifecycle instanceof LifecycleRegistry) {
                // 调用 LifecycleRegistry 的 handleLifecycleEvent 方法
                ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
            }
        }
    }
}

ReportFragment工作流程

  • dispatch(Activity activity, Lifecycle.Event event) 方法:通过 activity 获取 LifecycleRegistry 对象,然后调用 handleLifecycleEvent 方法来将生命周期变化通知给 LifecycleRegistry
  • 调用 dispatch 方法时机:在生命周期变化时会调用该方法。

当 API 级别大于或等于 29 时

  • dispatch(Activity activity, Lifecycle.Event event) 方法依然会被调用,但不是在 ReportFragment 的生命周期变化中调用。
  • registerActivityLifecycleCallbacks(new LifecycleCallbacks()):监听 Activity 生命周期变化,然后调用 dispatch 方法。

5. LifecycleRegistry 通知观察者生命周期状态变化

ActivityFragment 生命周期状态变化时,LifecycleRegistry 调用 handleLifecycleEvent 方法,更新状态并通知所有观察者:

/**
 * 设置当前状态并通知观察者
 *
 * @param event 接收到的事件
 */
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
    enforceMainThreadIfNeeded("handleLifecycleEvent");
    moveToState(event.getTargetState());
}

handleLifecycleEvent 方法中先调用了 event.getTargetState() 方法,根据 event 得到 State,然后调用 moveToState 方法设置新状态。getTargetState 方法源码如下:

/**
 * 根据Event获取State
 */
@NonNull
public Lifecycle.State getTargetState() {
    switch (this) {
        case ON_CREATE:
        case ON_STOP:
            return Lifecycle.State.CREATED;
        case ON_START:
        case ON_PAUSE:
            return Lifecycle.State.STARTED;
        case ON_RESUME:
            return Lifecycle.State.RESUMED;
        case ON_DESTROY:
            return Lifecycle.State.DESTROYED;
        case ON_ANY:
            break;
    }
    throw new IllegalArgumentException(this + " has no target state");
}

getTargetState 方法比较好理解,比如当前执行了 ON_CREATE 事件或者 ON_STOP 事件,那么状态就会处于 CREATED。继续看 moveToState 方法,如下:

private void moveToState(Lifecycle.State next) {
    //如果状态没有变化,直接return
    if (mState == next) {
        return;
    }
    //设置新状态
    mState = next;

    //mAddingObserverCounter:正在添加观察者数量
    if (mHandlingEvent || mAddingObserverCounter != 0) {
        //mNewEventOccurred:是否有新事件产生
        mNewEventOccurred = true;
        // we will figure out what to do on upper level.
        return;
    }
    //mHandlingEvent: 是否在处理事件
    mHandlingEvent = true;
    sync();
    mHandlingEvent = false;
}

moveToState 方法设置新状态,然后调用 sync 方法。在 Lifecycle 中,通过三个变量:mHandlingEventmNewEventOccurredmAddingObserverCounter 的配合,来解决事件嵌套引起的 sync() 多次执行。初次了解 Lifecycle 原理时,可以先忽略这三个变量,后续了解 Lifecycle 大概流程后再来思考这个问题。下面继续看 sync 方法,源码如下:

// happens only on the top of stack (never in reentrance),
// so it doesn't have to take in account parents
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.");
    }
    //isSynced():状态是否是同步的
    //map中保存的首尾节点的观察者状态以及mState记录的当前状态相同,说明已同步
    while (!isSynced()) {
        mNewEventOccurred = false;
        //比较mState和尾节点状态
        if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
            //状态向后
            backwardPass(lifecycleOwner);
        }
        Map.Entry<LifecycleObserver, LifecycleRegistry.ObserverWithState> newest = mObserverMap.newest();
        //比较mState和首节点状态
        if (!mNewEventOccurred && newest != null
                && mState.compareTo(newest.getValue().mState) > 0) {
            //状态向前
            forwardPass(lifecycleOwner);
        }
    }
    mNewEventOccurred = false;
}

sync 方法中,会根据当前状态和 mObserverMap 中的 eldestnewest 的状态做对比,判断当前状态是向前还是向后。比如由 STARTEDRESUMED 是状态向前,反过来就是状态向后。forwardPassbackwardPass 方法的代码类似,这里以 forwardPass 为例:

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对象
        ObserverWithState observer = entry.getValue();
        //比较当前状态mState和observer记录的状态
        while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
                && mObserverMap.contains(entry.getKey()))) {
            pushParentState(observer.mState);
            //upFrom:状态向前。比如observer.mState是STARTED,则变为RESUME
            final Event event = upFrom(observer.mState);
            if (event == null) {
                throw new IllegalStateException("no event up from " + observer.mState);
            }
            //调用ObserverWithState的dispatchEvent方法,通知观察者
            observer.dispatchEvent(lifecycleOwner, event);
            popParentState();
        }
    }
}

forwardPass 方法中,会同步状态,然后调用 ObserverWithStatedispatchEvent 方法,通知观察者。

ObserverWithState 是观察者 LifecycleObserver 的包装类,使其带有生命周期状态。

并提供了 dispatchEvent 方法,在 dispatchEvent 方法中通知观察者生命周期的变化。

static class ObserverWithState {
    //生命周期状态--Lifecycle中定义的enum State{}
    State mState;
    //观察者对象
    LifecycleEventObserver mLifecycleObserver;

    ObserverWithState(LifecycleObserver observer, State initialState) {
        //这里的observer对象可能是LifecycleEventObserver类型,
        //也可能是FullLifecycleObserver类型,
        //lifecycleEventObserver方法将对象统一转化为LifecycleEventObserver类型。
        mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);

        //初始化状态
        mState = initialState;
    }

    //分发事件
    void dispatchEvent(LifecycleOwner owner, Event event) {
        //根据Event得出当前最新的State状态
        State newState = event.getTargetState();
        mState = min(mState, newState);
        //触发观察者对象的onStateChanged()方法
        mLifecycleObserver.onStateChanged(owner, event);
        //更新状态
        mState = newState;
    }
}

总结

通过使用 Lifecycle 组件,开发者可以将生命周期相关的逻辑与业务逻辑分离,使代码更加模块化和易于维护。具体实现中,通过添加 LifecycleObserver 观察者,可以在 ActivityFragment 的生命周期变化时接收通知并执行相应操作。LifecycleRegistryActivityFragment 的生命周期方法中调用 handleLifecycleEvent,从而触发观察者的 onStateChanged 方法。