EventBus vs Callbacks, which to use when?

Mendhak picture Mendhak · Mar 12, 2015 · Viewed 9.9k times · Source

I have many Activities which raise background tasks; the Activities will pass themselves in as having implemented a listener callback, so that the background tasks can raise an event on the Activities. The Activities in turn can show something on the UI to indicate that a background activity passed or failed.

Alternatively, I could use an EventBus, wherein I get the Activity to register itself as a listener/subscriber. I can have a background tasks raise an event on the EventBus and the Activity listening to it can handle it.

What are the advantages of one over the other? When would you use one over the other? (Code cleanliness? Performance? Caveats?)


Follow up - I did end up using EventBus. The code is definitely a lot cleaner and there aren't callbacks hanging out everywhere. The IDE (IntelliJ) thinks that the onEvent methods are unused, so I created an annotation

@Target({ElementType.METHOD})
public @interface EventBusHook {}

and placed it over my onEvent methods. Then Alt+Clicked on it and asked IntelliJ to not treat it as unused.

@EventBusHook
public void onEvent(MyEventType myEventType){

Answer

Vasiliy picture Vasiliy · Apr 28, 2017

I disagree with @nnuneoi's answer.

Event bus has just one single advantage: it allows for communication between components which are "unaware" of each other's existence.

And there are several disadvantages:

  1. The components become loosely coupled by dependency on both event bus and specific event type
  2. The coupling described in #1 above is not strong
  3. The coupling described in #1 above is not evident
  4. Event bus introduces performance overhead over simple callbacks
  5. If event bus holds a strong reference to subscribers (as is the case with e.g. GreenRobot's EventBus), then unregistered subscribers will cause memory leaks

Given all these disadvantages, simple callbacks should be the default implementation choice.

Event bus should be used only when direct coupling is not desired or hard to implement. For example:

  1. Sending events from Service to Activity
  2. Exchanging events between independent Fragments
  3. Application wide events (e.g. user login/logout)

If the communicating components are already "aware" of each other's existence, there is no need for them communicating via event bus.