Search code examples
androidevent-bus

EventBus Unable to start activity


I'm building an app Android and I want to send an EventBus from my Service class to my Activity.

So this is my activity code:

    @Override
    protected void onResume() {
        super.onResume();
        startServiceScan(true);
    }

    @Override
    public void onStart() {
        super.onStart();
        EventBus.getDefault().register(BlePowerService.class);
    }

    @Override
    protected void onPause() {
        EventBus.getDefault().unregister(BlePowerService.class);
        super.onPause();
    }

    @Override
    public void onDestroy() {

        super.onDestroy();
        EventBus.getDefault().unregister(BlePowerService.class);
    }

// This method will be called when a HelloWorldEvent is posted
    public void onEvent(MessageEvent event){
        // your implementation
        System.out.print("");
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void getEventBusData(MessageEvent messageEvent) {
        if (messageEvent != null) {
           //TO-DO
        }

    }

This is the code in my BlePowerService class:

EventBus.getDefault().post(new MessageEvent("update"));

if I try to start my application, I have this error:

    java.lang.RuntimeException: Unable to start activity 
ComponentInfo{com.care.devicesensor/com.care.devicesensor.BLEActivity}: 
org.greenrobot.eventbus.EventBusException: Subscriber class java.lang.Class and its super classes have 
no public methods with the @Subscribe annotation
...............
Caused by: org.greenrobot.eventbus.EventBusException: Subscriber class java.lang.Class 
and its super classes have no public methods with the @Subscribe annotation

The error id onStart method from my Activity class.

//EDIT

I add my MessageEvent class:

public class MessageEvent {
    public final String message;

    public MessageEvent(String message) {
        this.message = message;
    }
}

Solution

  • So you have done a few things wrong here...

    First, looking at Androids activity lifecycle, if you register something in onStart() you should then unregister it in onStop(), and if you register something in onResume() you should then unregister it in onPause(). Otherwise, you register it when the the activity starts but when the user puts the app into the background for a bit, it will unregister, and it will not register again as the app hasn't started, it has just resumed.

    Secondly, if you look at the EventBus GitHub you should be registering the Activity and not a class.

    Here is an example:

    @Override
    public void onStart() {
        super.onStart();
        EventBus.getDefault().register(this);
    }
    
    @Override
    public void onStop() {
        super.onStop();
        EventBus.getDefault().unregister(this);
    }
    
    @Subscribe(threadMode = ThreadMode.MAIN)  
    public void onMessageEvent(MessageEvent event) {
        /* Do something */
    }
    

    Now you can call the onMessageEvent function from anywhere in the app with the code:

    EventBus.getDefault().post(new MessageEvent("update"));
    

    On an extra note, this could be a result of your ProGuard. Luckily there are EventBus ProGuard rules we can use to prevent subscribers from being removed from your code:

    -keepattributes *Annotation*
    -keepclassmembers class * {
        @org.greenrobot.eventbus.Subscribe <methods>;
    }
    -keep enum org.greenrobot.eventbus.ThreadMode { *; }
    
    # Only required if you use AsyncExecutor
    -keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
        <init>(java.lang.Throwable);
    }