0

My app uses Otto all over the place but I am consistently running into the same Runtime Exception crash. This is happening with several different events and that makes me think I am not implementing otto correctly. I am using the Main Thread Bus technique as follows:

/**
 * Otto bus that enforces bus messages posted on the main thread
 * Adapted from: http://stackoverflow.com/questions/15431768/how-to-send-event-from-service-to-activity-with-otto-event-bus
 */
public class MXRMainThreadBus extends Bus {
    private final Bus mBus;
    private final Handler mHandler = new Handler(Looper.getMainLooper());

    public MXRMainThreadBus(final Bus bus) {
        if (bus == null) {
            throw new NullPointerException("bus must not be null");
        }
        mBus = bus;
    }

    @Override public void register(Object obj) {
        mBus.register(obj);
    }

    @Override public void unregister(Object obj) {
        mBus.unregister(obj);
    }

    @Override public void post(final Object event) {
        if (Looper.myLooper() == Looper.getMainLooper()) {
            mBus.post(event);
        } else {
            mHandler.post(new Runnable() {
                @Override public void run() {
                    mBus.post(event);
                }
            });
        }
    }
}

Here is my Bus Provider:

/**
 * Otto Bus Provider singleton
 */
public class BusProvider {
    private static MXRMainThreadBus BUS;

    private BusProvider() {}

    public static Bus getInstance() {
        if(BUS == null) {
            BUS = new MXRMainThreadBus(new Bus());
        }
        return BUS;
    }
}

Here is the stack trace (For the most common one):

java.lang.RuntimeException
com.squareup.otto.Bus.throwRuntimeException(Bus.java:444)
com.squareup.otto.Bus.dispatch(Bus.java:374)
com.squareup.otto.Bus.dispatchQueuedEvents(Bus.java:355)
com.squareup.otto.Bus.post(Bus.java:324)
com.myxer.android.unicorn.utils.MXRMainThreadBus.post(MXRMainThreadBus.java:33)
com.myxer.android.unicorn.api.MXRApiController$1.onResponse(MXRApiController.java:173)
com.myxer.android.unicorn.api.MXRApiController$1.onResponse(MXRApiController.java:170)
com.myxer.android.unicorn.volley.GsonRequest.deliverResponse(GsonRequest.java:117)
com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
android.os.Handler.handleCallback(Handler.java:725)
android.os.Handler.dispatchMessage(Handler.java:92)
android.os.Looper.loop(Looper.java:137)
android.app.ActivityThread.main(ActivityThread.java:5185)
java.lang.reflect.Method.invokeNative(Native Method)
java.lang.reflect.Method.invoke(Method.java:511)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:564)
dalvik.system.NativeStart.main(Native Method)
Caused by: com.myxer.android.unicorn.fragments.MXRStationGridFragment.onStationReceivedImpl(MXRStationGridFragment.java:142)
com.myxer.android.unicorn.fragments.tabhosted.MXRRelatedStationsGridFragment.onStationReceived(MXRRelatedStationsGridFragment.java:75)
java.lang.reflect.Method.invokeNative(Native Method)
java.lang.reflect.Method.invoke(Method.java:511)
com.squareup.otto.EventHandler.handleEvent(EventHandler.java:89)
com.squareup.otto.Bus.dispatch(Bus.java:372)
com.squareup.otto.Bus.dispatchQueuedEvents(Bus.java:355)
com.squareup.otto.Bus.post(Bus.java:324)
com.myxer.android.unicorn.utils.MXRMainThreadBus.post(MXRMainThreadBus.java:33)
com.myxer.android.unicorn.api.MXRApiController$1.onResponse(MXRApiController.java:173)
com.myxer.android.unicorn.api.MXRApiController$1.onResponse(MXRApiController.java:170)
com.myxer.android.unicorn.volley.GsonRequest.deliverResponse(GsonRequest.java:117)
com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
android.os.Handler.handleCallback(Handler.java:725)
android.os.Handler.dispatchMessage(Handler.java:92)
android.os.Looper.loop(Looper.java:137)
android.app.ActivityThread.main(ActivityThread.java:5185)
java.lang.reflect.Method.invokeNative(Native Method)
java.lang.reflect.Method.invoke(Method.java:511)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:564)
dalvik.system.NativeStart.main(Native Method)
SamIAmHarris
  • 2,158
  • 3
  • 16
  • 19
  • That's not a complete stack trace. You are probably catching the exception in your IDE. Run past the point of the exception, then examine LogCat to see the complete stack trace, including the error message itself. – CommonsWare May 12 '14 at 22:41
  • I assume, this is a concurrency issue you run into. It looks you can register/unregister in any thread, but posting happens in main thread only. If this assumption is true, then wrapping subscribe/unsubscribe similarly to post event must do the trick. – sergej shafarenka Jun 14 '14 at 11:36

1 Answers1

0

If you run the Bus on anoher thread then the main Thread, then you will run into that exception. The Otto Bus provider runs on the main thread. There exists however a Wrapper that allows passing events on to other threads than the main one. This can be used for Services when you try to pass messages from a running background service to a UI thread. Here is the wrapper:

public class MainThreadBus extends Bus
  {
    private final Bus     mBus;
    private final Handler mHandler = new Handler(Looper.getMainLooper());

    public MainThreadBus(final Bus bus)
      {
        if (bus == null)
          {
            throw new NullPointerException("bus must not be null");
          }
        mBus = bus;
      }

    @Override
    public void register(Object obj)
      {
        mBus.register(obj);
      }

    @Override
    public void unregister(Object obj)
      {
        mBus.unregister(obj);
      }

    @Override
    public void post(final Object event)
      {
        if (Looper.myLooper() == Looper.getMainLooper())
          {
            mBus.post(event);
          }
        else
          {
            mHandler.post(new Runnable()
              {
                @Override
                public void run()
                  {
                    mBus.post(event);
                  }
              });
          }
      }
  }
greenspand
  • 749
  • 2
  • 8
  • 15