Mendhak
Mendhak

Reputation: 8785

EventBus vs Callbacks, which to use when?

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){

Upvotes: 28

Views: 12118

Answers (5)

Sir Codesalot
Sir Codesalot

Reputation: 7283

In a single sentence, event bus is a classic God Object and is therefore considered an anti-pattern and should be avoided.

Upvotes: 0

Samuel Owino
Samuel Owino

Reputation: 745

I would go with the EventBus because of the loose coupling and cleaner code. Also, the fact that using an EventBus such as Greenrobot automatically does all the boilerplate for me and allows me to register & deregister observers right from Activity Lifecycle methods (onStart and onDestroy|onStop) is great. Implementing callbacks and still managing to control Activity lifecycle management for those callbacks is an unnecessary headache and involves a lot of unnecessary boilerplate.

Also, apparently all garbage collectors think weak reference is great-Event bus gives your observers and components exactly that. Its the basis of the Observer pattern.

Upvotes: 1

oopexpert
oopexpert

Reputation: 755

You should check if your event is globally unique on the semantic view. Either an subscriber is interested in the event or not. If not he shouldn't subscribe.

Event-Bus mechanism is right if you really have a publisher-subscriber relationship. The event must be totally independent of the receiver.

So a subscriber that discard the event for any reason of responsibility ("I am not responsible the event even if I am registered") is a strong indicator that using an Event-Bus is wrong. Then you should consider using dedicated listeners.

Upvotes: 1

Vasiliy
Vasiliy

Reputation: 16238

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.

Upvotes: 55

nuuneoi
nuuneoi

Reputation: 1798

Benefits of using EventBus:

  • Your code will look much more clean
  • Your code will become more modular which will allow you to easily create test case for your code
  • Avoid memory leaks from bad object references which lock the object and does not allow Garbage Collector to clean it up
  • Could have more than one receiver a time, that it much like broadcasting
  • Simplify multiple interfaces into a single one, EventBus
  • In an interface class, you need to override every single method in the class that is inherited. With EventBus, you can listen for just an event that you really want

But bad part is you might be a little bit more headache with the function declaration since IDE couldn't help you with auto-complete.

My suggestion is, if you find that you have to create a custom listener, then please consider EventBus, it might be a better choice for most of (if not all) of your requirements/cases.

Anyway, it is all your choice after all =)

Upvotes: 26

Related Questions