LifecycleRegistry 的 handleLifecycleEvent 是否给我错误的事件回调?什么改变了?

Is LifecycleRegistry's handleLifecycleEvent giving me the wrong event callback? What changed?

直到几周前,我的 LifeCycleOwnerAwareObserver class 工作正常。

它是为了在 Destroy 上自分离而设计​​的。

@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
    Log.d(TAG, "onStateChanged: event is: " + event.name());
    Lifecycle.State state = source.getLifecycle().getCurrentState();

    Log.println(Log.WARN, TAG, "onStateChanged: state is: " + state.name());

    if (state.isAtLeast(INITIALIZED) && !state.equals(DESTROYED)) {
        observer.get().accept(event);
    } else if (state.equals(DESTROYED)) {
        observer.get().accept(event);
        observer.set(() -> null);
        source.getLifecycle().removeObserver(this);
    }
}

这个想法是构建生命周期感知组件来处理自动注销。

我项目的 90% 都依赖于这个组件...

我没有察觉到任何变化,特别是在监听片段的适配器上,这是我看到的唯一一个奇怪的行为,其中 onViewCreated(ON_START 回调将观察者附加到片段的 LifeCycleOwnerLiveData)轻微触发在真正的 onViewCreated() 之后,但仅当从 backStack 返回时...这一点都不好,但通过一些预防措施,它可以被忽略。

但这是其中最奇怪的...

我有一个自定义视图 (ViewParticle.class),它有自己的 LifeCycle,实现了 LifeCycleRegistry。

这段代码几周前就可以工作了...因为我没有一直测试所有的东西,所以我不确定这段代码是什么时候停止工作的:

private final MyLifeCycleOwner mViewLifecycleOwner = new MyLifeCycleOwner();

@Override
public void viewDestroyed() {
    Lifecycle.Event event = Lifecycle.Event.ON_DESTROY;
    Log.d(TAG, "viewDestroyed: event is: " + event.toString());
    mViewLifecycleOwner.handleLifecycleEvent(event);
}

接收端:

    @Override
    public void viewPrepared() {
        lifecycleSupplier = () -> mViewLifecycleOwner;
        Lifecycle lCRef = mViewLifecycleOwner.getLifecycle();

        //The callback HERE!!
        lCRef.addObserver(
                new LifeCycleOwnerAwareObserver(
                        event -> {
                            Log.d(TAG, "viewPrepared: event is: " + event.name());
                            if (event.equals(Lifecycle.Event.ON_DESTROY)) lastResponseProvider.run();
                        }
                )
        );

        lifeCycleProvider.run();
        mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
        mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);

    }

执行 viewDestroyed() 时,日志显示此内容:

D/ViewParticle: viewDestroyed: event is: ON_DESTROY 
D/MyLifeCycleOwner: handleLifecycleEvent: event is: ON_DESTROY 
D/LifeCycleOwnerAwareObse: onStateChanged: event is: ON_STOP 
W/LifeCycleOwnerAwareObse: onStateChanged: state is: DESTROYED 
D/ViewParticle: viewPrepared: event is: ON_STOP

如您所见,Event.ON_DESTROY 枚举转换为: 一)Lifecycle.State.DESTROYED b) Lifecycle.Event.ON_STOP

这是不可能的,因为 getStateAfter() 方法如下:

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

这意味着事件永远不会不同于状态,因为状态是事件的产物,而triggers/begins回调是事件,而不是状态。

这意味着如果状态被摧毁,事件必须是ON_DESTROYED。

我无法解释这里发生的事情..

我不会过多地研究这个问题,但乍一看答案似乎在这里:

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

backwardPass(lifecycleOwner);forwardPass(lifecycleOwner); 方法似乎在假设 mState.compareTo(newest.getValue().mState) > 0mState.compareTo(mObserverMap.eldest().getValue().mState) < 0 条件永远不会大于 1 的情况下工作,所以即使答案是“正确的,因为它是 2”,forwardPass() 方法只会推进生命周期中的单个节点,从其先前值之一开始...... 此行为使 getStateAfter(Event event) 方法的功能变得毫无意义。

顺便说一句,我记得这特别给我带来了问题:

mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);

在我上面的代码中,这意味着这实际上给我带来了问题,所以现在需要澄清的奇怪的事情是为什么它首先工作正常? IDK.

答案是这样的:

@Override
public void viewDestroyed() {
    Lifecycle.Event event = Lifecycle.Event.ON_STOP;
    Log.d(TAG, "viewDestroyed: event is: " + event.toString());
    mViewLifecycleOwner.handleLifecycleEvent(event);
    Lifecycle.Event event2 = Lifecycle.Event.ON_DESTROY;
    Log.d(TAG, "viewDestroyed: event is: " + event.toString());
    mViewLifecycleOwner.handleLifecycleEvent(event2);
}

要求是需要按顺序遍历枚举,直到达到所需的程度。

public enum Event {

    ON_CREATE,

    ON_START,

    ON_RESUME,

    ON_PAUSE,

    ON_STOP,

    ON_DESTROY,

    ON_ANY
}

到目前为止,似乎唯一可跳过的枚举是:

ON_RESUMEON_PAUSE