GreenRobot EventBusException: Subscriber class already registered with event class

I have a MainActivity and a Service in my android app. I have logged both EventBus events and when I start the service from the main activity manually using the switch everything works fine. However, when I start the service from the AlarmManager, my application crashes with the following stack trace:

05-08 21:21:00.051: E/AndroidRuntime(22362): FATAL EXCEPTION: main
05-08 21:21:00.051: E/AndroidRuntime(22362): Process: com.hesselapplications.shade, PID: 22362
05-08 21:21:00.051: E/AndroidRuntime(22362): java.lang.RuntimeException: Unable to start service com.hesselapplications.shade.ShadeService@39251d8 with Intent { cmp=com.hesselapplications.shade/.ShadeService }: de.greenrobot.event.EventBusException: Subscriber class com.hesselapplications.shade.ShadeService already registered to event class com.hesselapplications.shade.EventBus.ColorChangedEvent
05-08 21:21:00.051: E/AndroidRuntime(22362):    at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2881)
05-08 21:21:00.051: E/AndroidRuntime(22362):    at android.app.ActivityThread.access$2100(ActivityThread.java:144)
05-08 21:21:00.051: E/AndroidRuntime(22362):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1376)
05-08 21:21:00.051: E/AndroidRuntime(22362):    at android.os.Handler.dispatchMessage(Handler.java:102)
05-08 21:21:00.051: E/AndroidRuntime(22362):    at android.os.Looper.loop(Looper.java:135)
05-08 21:21:00.051: E/AndroidRuntime(22362):    at android.app.ActivityThread.main(ActivityThread.java:5221)
05-08 21:21:00.051: E/AndroidRuntime(22362):    at java.lang.reflect.Method.invoke(Native Method)
05-08 21:21:00.051: E/AndroidRuntime(22362):    at java.lang.reflect.Method.invoke(Method.java:372)
05-08 21:21:00.051: E/AndroidRuntime(22362):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
05-08 21:21:00.051: E/AndroidRuntime(22362):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
05-08 21:21:00.051: E/AndroidRuntime(22362): Caused by: de.greenrobot.event.EventBusException: Subscriber class com.hesselapplications.shade.ShadeService already registered to event class com.hesselapplications.shade.EventBus.ColorChangedEvent
05-08 21:21:00.051: E/AndroidRuntime(22362):    at de.greenrobot.event.EventBus.subscribe(EventBus.java:179)
05-08 21:21:00.051: E/AndroidRuntime(22362):    at de.greenrobot.event.EventBus.register(EventBus.java:165)
05-08 21:21:00.051: E/AndroidRuntime(22362):    at de.greenrobot.event.EventBus.register(EventBus.java:133)
05-08 21:21:00.051: E/AndroidRuntime(22362):    at com.hesselapplications.shade.ShadeService.onStartCommand(ShadeService.java:51)
05-08 21:21:00.051: E/AndroidRuntime(22362):    at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2864)
05-08 21:21:00.051: E/AndroidRuntime(22362):    ... 9 more

      

Here is my MainActivty code:

public class MainActivity {

    private SwitchCompat mSwitch;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mSwitch = (SwitchCompat) findViewById(R.id.switch_filter);
        mSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) Shade.startShade(MainActivity.this);
                else Shade.stopShade(MainActivity.this);
            }
        });
    }

    public void onEventMainThread(ShadeStartEvent event) {
        mSwitch.setChecked(true);
    }

    public void onEventMainThread(ShadeStopEvent event){
        mSwitch.setChecked(false);
    }

    @Override
    protected void onStart() {
        super.onStart();
        mSwitch.setChecked(Shade.isActive);
        EventBus.getDefault().register(this);
    }

    @Override
    protected void onStop() {
        EventBus.getDefault().unregister(this);
        super.onStop();
    }

}

      

And here is my service code:

public class MyService extends Service {

    public void onEvent(ShadeStopEvent event) {
        EventBus.getDefault().unregister(ShadeService.this);
    }

    public void onEvent(ColorChangedEvent event){

    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        Shade.stopShade(this);
        super.onTaskRemoved(rootIntent);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        EventBus.getDefault().register(ShadeService.this);
        return START_NOT_STICKY;
    }

}

      

Finally, there is a class with startShade and stopShade methods. It is also a broadcast receiver that receives the above alarm:

public class Shade extends BroadcastReceiver {

    public static boolean isActive;

    @Override
    public void onReceive(Context context, Intent intent) {
        if (isStartAlarm) {
            startShade(context);
        } else if (isStopAlarm) {
            stopShade(context);
        }
    }

    public static void startShade(Context context) {
        if (!isActive) {
            Intent intent = new Intent(context, ShadeService.class);
            context.startService(intent);
            EventBus.getDefault().post(new ShadeStartEvent());
            isActive = true;
        }
    }

    public static void stopShade(Context context) {
        if (isActive) {
            EventBus.getDefault().post(new ShadeStopEvent());
            Intent intent = new Intent(context, ShadeService.class);
            context.stopService(intent);
            isActive = false;
        }
    }

}

      

What is causing this crash. How can I solve it?

+3


source to share


2 answers


The problem is that you are trying to register the service twice, as you can see in the traceback. The service is not unregistered, so the easiest option for you is to check if the service is registered before registering it, EventBus.getDefault().isRegistered(...)

or to check why the service is not stopped and therefore still registered. For example:



if (!EventBus.getDefault().isRegistered(this)) {
    EventBus.getDefault().register(this);
}

      

+31


source


Maybe it's better to unregister from the event in the onPause () callback?



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

      

+5


source







All Articles