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

myss37ts  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(309)

直到几周前,我的LifecycleOwneraWareObservator课程还不错。
它的设计目的是在破坏时自动分离。

@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\u start回调将一个观察者附加到片段的lifecycleownerlivedata)在真正的onviewcreated()之后被稍微触发,但只有在从backbackback回来时才触发。。。这一点都不好,但如果采取一些预防措施,它可能会被忽略。
但这是最奇怪的。。。
我有一个自定义视图(viewparticle.class),它有自己的生命周期,实现了生命周期注册表。
这个代码几周前还在运行。。。由于我没有不断地测试所有的东西,我不确定在什么时候停止工作这里是代码:

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 枚举正在转换为:a) Lifecycle.State.DESTROYED (二) 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);
}

这意味着一个事件永远不会与一个状态不同,因为一个状态是一个事件的产物,而触发/开始回调的是事件,而不是状态。
这意味着,如果状态被销毁,则事件必须处于销毁状态。
我无法解释这里发生了什么。。

093gszye

093gszye1#

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

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) > 0 以及 mState.compareTo(mObserverMap.eldest().getValue().mState) < 0 条件永远不会大于1,因此即使答案是“true,因为它是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_RESUME 以及 ON_PAUSE

相关问题