In my Android apps i'm using Otto as event bus and Dagger for dependency injection.
In the userguide of Otto and in many blog posts it's recommended to use injection to get a bus singleton. I have done that for some time, but lately i'm getting more doubtful if injecting the bus has any advantages over using a simple static singleton.
With injection i have to inject every custom View or ViewHolder that i want to be able to post UI events on the bus. Especially with dagger it seems a bit clumsy to inject every class where i need the bus. Sure, i could pass the bus by constructor or setter method, but that can be kind of clumsy too if you think about an adapter with many different view types for example.
And i don't see any advantages in injecting the bus. In case of Otto a concrete implementation is injected (an instance of Bus) and that will never change. Wrapping Otto for de-coupling does not make any sense if think, because of the way subscription works.
So, does anyone see any advantages of injecting Otto that i don't see?
In my opinion, you should definitely wrap the event bus in your own class and use dependency injection techniques in order to pass it to clients.
There are several advantages to this approach over simply obtaining a reference through a call to static getInstance()
method:
I say that it is possible that you're abusing event bus because I don't really see why would you need to have a reference to it in View
subclasses. I'd guess that you post notifications about user interactions to event bus, and then subscribe Activity
or Fragment
to event bus in order to intercept these events. Event bus is a wrong tool in this case (even though it works great).
The reason why event bus is a wrong tool in this case is because Fragments
and Activity
can have a direct access to the contained View
objects. You can get references to these Views
and register Fragments
and Activities
as listeners. No need to decouple anything here.
On contrary: think about a case where you go and refactor your Views
in such a way that nothing being posted to event bus anymore (say, business requirements changed). Since Views
notifications are only loosely coupled to containing Fragment
or Activity
through event bus, it is very probable that you'll forget to remove the events handling logic from Fragment
and Activity
, thus leaving "dead code" behind. This gets messy very quickly.
The better practice would be to use Observer design pattern and let Views
notify Activities
and Fragments
directly, and only when handling involves another component (which can't be easily reached from Fragment
and Activity
; e.g. another Fragment
or Activity
) will these components post events to event bus. If you follow this approach, you will need to have a reference to event bus in "top level components" only, and no struggling will be involved.
P.S. I have recently published a blog post which introduces some best practices for dependency injection in Android.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With