1

I'm using Otto as my event bus in my android application.
I had to make sure that certain events are called in the main thread, or not in the main thread, for that I created my own bus class which uses Otto like so:

class MyEventBus {
    private final Bus anyThreadBus;
    private final Bus mainThreadBus;
    private final Bus notMainThreadBus;

    private final Handler mainThreadHandler;

    public enum Strategy {
        Any,
        Main,
        NotMain
    }

    MyEventBus() {
        this.anyThreadBus = new Bus(ThreadEnforcer.ANY);
        this.mainThreadBus = new Bus(ThreadEnforcer.MAIN);
        this.notMainThreadBus = new Bus(ThreadEnforcer.ANY);
        this.mainThreadHandler = new Handler(Looper.getMainLooper());
    }

    public void register(Object object) {
        this.register(object, Strategy.Any);
    }

    public void register(Object object, Strategy strategy) {
        switch (strategy) {
            case Main:
                this.mainThreadBus.register(object);
                break;

            case NotMain:
                this.notMainThreadBus.register(object);
                break;

            case Any:
            default:
                this.anyThreadBus.register(object);
        }
    }

    public void unregister(Object object) {
        try {
            this.anyThreadBus.unregister(object);
        } catch (Exception e) {}

        try {
            this.mainThreadBus.unregister(object);
        } catch (Exception e) {}

        try {
            this.notMainThreadBus.unregister(object);
        } catch (Exception e) {}
    }

    public void post(Object event) {
        this.anyThreadBus.post(event);
        this.enforceOnMainThread(event);
        this.enforceOnNotMainThread(event);
    }

    public void post(Object event, Strategy strategy) {
        switch (strategy) {
            case Main:
                this.enforceOnMainThread(event);
                break;

            case NotMain:
                this.enforceOnNotMainThread(event);
                break;

            case Any:
            default:
                this.anyThreadBus.post(event);
        }
    }

    private void enforceOnNotMainThread(final Object event) {
        if (MyEventBus.onMainThread()) {
            // MyApplication.pool() returns a shared thread pool for the application
            MyApplication.pool().execute(new Runnable() {
                @Override
                public void run() {
                    notMainThreadBus.post(event);
                }
            });
        } else {
            this.notMainThreadBus.post(event);
        }
    }

    private void enforceOnMainThread(final Object event) {
        if (MyEventBus.onMainThread()) {
            this.mainThreadBus.post(event);
        } else {
            this.mainThreadHandler.post(new Runnable() {
                @Override
                public void run() {
                    mainThreadBus.post(event);
                }
            });
        }
    }

    private static boolean onMainThread() {
        return Looper.myLooper() == Looper.getMainLooper();
    }
}

I have two questions:

  1. In my post methods I post the event on all of the 3 buses, and that's because I don't know if the posted event has a registered class in a certain bus. Is there a way to know? something like:
    if (this.anyThreadBus.has(event)) { ... } Is there a way to do this other than maintaining a map of event classes to registered classes per bus?

  2. Currently each registered class has an enforcement per call it made to register. But it would be best if I couldn't specify the enforcement per method and not for the entire class, something like:
    @Subscribe(enforcement = Strategy.Main) public void handleMyEvent(MyEvent event) { ... }
    Can that be done somehow?

Thanks.

Nitzan Tomer
  • 155,636
  • 47
  • 315
  • 299

1 Answers1

0

Maybe it's time to switch your EventBus implementation? Check out if that one would make live easier for you: http://greenrobot.org/eventbus/documentation/delivery-threads-threadmode/

Markus Junginger
  • 6,950
  • 31
  • 52