AndroidアプリにMainActivityとServiceがあります。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);
}