I have a MainActivity and a Service in my android app. I have registered both to the EventBus and when I start the service from the main activity manually via a switch everything works fine. However, when I start the service from an AlarmManager alarm I my app 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;
}
}
Lastly here is class with the startShade and stopShade methods. This is also the broadcast receiver that receives the aforementioned 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 resolve it?
The issue is the you are trying to register the service twice as you can see in the trace. The service isn't unregistered therefore the easiest option for you is to check whether the service is registered before you register it EventBus.getDefault().isRegistered(...)
or check why the service isn't stopped and therefore still registered. For example:
if (!EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().register(this);
}