EventBus icon indicating copy to clipboard operation
EventBus copied to clipboard

Event is lost after unregister/

Open KadarRobert opened this issue 10 years ago • 3 comments

Hello, I've a found a corner case when you post an event (non-main-thread) to a MainThread the event is lost and no NoSubscriberEvent is sent.

Latest code from git. Steps: 1.) Post an Event from a non-main-thread. 2.) Unregister after the post method was called.

Expected: 2.) A NoSubscriberEvent should be sent.

Actual: 2.) The event is lost.

I've created a a Unit test to ilustrate this issue.

public class TestPostingIssue extends AbstractEventBusTest {

    // this test will fail.
    public void testNoEventDelivered() {
        // I've created a dummy class to ilustrate the corner case issue.
        TestClass testClass = new TestClass();

        /**
         * Basically register a class, post an event and unregister the class.
         * The event will not be sent and also no NoSubscriberEvent will be
         * deliver. I couldn't find any warnings in the logs.
         */
        eventBus.register(testClass);
        // a new String Event is posted from the Test Thread to the MainThread.
        eventBus.post(new String("Test"));
        eventBus.unregister(testClass);

        try {
            // sleep 1sec just to be sure.
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // Test if we received a NoSubscriberEvent then there should not be
        // any String Event. Else we should have received the String Event.
        if (testClass.getNoSubscriberEvent() != null) {
            assertNull(testClass.getStringValue());
        } else {
            assertNotNull(testClass.getStringValue());
        }
    }

    // this test will not fail.
    public void testEventDeliverd() {
        final TestClass testClass = new TestClass();
        eventBus.register(testClass);
        // a new String Event is posted from the Main Thread to the MainThread.

        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
                eventBus.post(new String("Test"));
                eventBus.unregister(testClass);
            }
        });

        try {
            // sleep 1sec just to be sure.
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // Test if we received a NoSubscriptionEvent then there should not be
        // any String Event. Else we should have received the String Event.
        if (testClass.getNoSubscriberEvent() != null) {
            assertNull(testClass.getStringValue());
        } else {
            assertNotNull(testClass.getStringValue());
        }
    }

    private static class TestClass {

        private String stringValue;
        private NoSubscriberEvent noSubscriberEvent;

        public void onEventMainThread(String event) {
            stringValue = event;
        }

        public void onEventMainThread(NoSubscriberEvent event) {
            noSubscriberEvent = event;
        }

        public NoSubscriberEvent getNoSubscriberEvent() {
            return noSubscriberEvent;
        }

        public String getStringValue() {
            return stringValue;
        }
    }

}

Hope this is helpful.

Thanks,

KadarRobert avatar May 28 '14 14:05 KadarRobert

I believe something like this is happening in my app. I have a sticky event that is posted with the state of a service. The service is started in my Application subclass and I postSticky state STARTING right in onCreate of the application, then after the service starts I postSticky STARTED state. My main activity uses registerSticky and sometimes does not get the event posted to it. It appears to happen (I believe) when the screen goes to sleep right as the application starts and it's semi-rare (probably 1/10 tries). I've got logging and I'm positive the event is lost. I do registerSticky/unregister from onResume/onPause respectively but even after onResume i don't get the state.

mwolfe38 avatar Aug 13 '15 18:08 mwolfe38

is this problem resolved ? because events get lost when screen is off

MrOplus avatar Jun 09 '18 10:06 MrOplus

Try the new MAIN_ORDERED thread mode, which always posts events to a main thread handler. -ut

greenrobot-team avatar Sep 03 '18 08:09 greenrobot-team