GreenRobot EventBusException: класс подписчика уже зарегистрирован в классе события

У меня есть MainActivity и Сервис в моем приложении для Android. Я зарегистрировался как на EventBus, и когда я запускаю службу из основной активности вручную через коммутатор, все работает нормально. Однако, когда я запускаю службу из-за тревоги AlarmManager, мое приложение вылетает со следующей трассировкой стека:

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

Вот мой код MainActivty:

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

}

А вот мой сервисный код:

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

}

Наконец, здесь класс с методами startShade и stopShade. Это также вещательный приемник, который получает вышеупомянутую тревогу:

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

}

Что является причиной этого сбоя. Как я могу решить это?

2 ответа

Проблема в том, что вы пытаетесь зарегистрировать сервис дважды, как вы видите на трассировке. Сервис не является незарегистрированным, поэтому самый простой вариант для вас - проверить, зарегистрирован ли сервис, прежде чем регистрировать его. EventBus.getDefault().isRegistered(...)или проверьте, почему служба не остановлена ​​и, следовательно, все еще зарегистрирована. Например:

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

Может быть, лучше отменить регистрацию в событии в обратном вызове onPause()?

@Override
protected void onPause() {
    super.onPause();
    EventBus.getDefault().unregister(this);
}
Другие вопросы по тегам