Can I use the Event Bus to decouple all of the application layers? I m trying to use the clean architecture. Normally the decoupling is made by a boundaries interfaces, I have seen some examples using RX observers for that. The question is can i use Event Bus to decouple the layers? and can the event bus handle such a job?
Event Bus is perfect for cross-cutting activities so you don't need to pass trough a middle layer to deliver an event if you don't need to.
For clean/onion/multi-layer architecture you don't need Event Bus but clear contracts between the layers i.e. boundary interfaces. They may or may not use RX.
You can fully decouple modules using on Event Bus with no interfaces whatsoever and then all components will be extremely decoupled, however it will become a hell to debug, maintain and super difficult to do anything meaningful :) So some kind of contract is always a good idea even when using Event Bus.
Combining Reactive Programming and Event Bus you can create highly decoupled event driven pico services bounded by some contracts around your Event Bus in order to improve clarity of the event/command/data flow.
I am personally using and working on RxHub which was born exactly from the need of passing cross-cutting events and easy data-flow operators chaining.
Related
My app is heavily depended on Local broadcast ,for every activity invocation am invoking the broadcast registration method so is it good to move to any event bus.
Two primary concerns of using Local broadcast Manager.
Every activity require the registration
Registration method execution time(Around 10 actions are registered)
I think the event bus will improve overall execution and performance of my app.
Most event bus libraries provide reflection-based registration which is less efficient than LocalBroadcastManager. The main reason for using the event bus would be coding ease.
afaik, there are some benefits using event-bus instead of LocalBroadcastManager:
Code decoupling.
By decoupling your code, you will minimize your class which formerly using LocalBroadcastManager. Simpler code less error and improve code readability.
Ease of Maintenance.
This somewhat related to no.1, decoupled code make it easy to maintained.
Localizing error.
Avoids complex and error-prone dependencies and life cycle issues.
Avoid further bugs.
EventBus FAQ
How is EventBus different to Android’s BroadcastReceiver/Intent system?
Unlike Android’s BroadcastReceiver/Intent system, EventBus uses
standard Java classes as events and offers a more convenient API.
EventBus is intended for a lot more uses cases where you wouldn’t want
to go through the hassle of setting up Intents, preparing Intent
extras, implementing broadcast receivers, and extracting Intent extras
again. Also, EventBus comes with a much lower overhead.
This question already has an answer here:
Android Pros & Cons: Event Bus and RxJava
(1 answer)
Closed 3 years ago.
I am confused about the difference between EventBus and RxJava in android. I need to implement one of them for my issue about notifying some components when some changes have been done, so that they can update their state.
Also, I read that EventsBus has became deprecated over RxJava and I don't know if this information is true or not.
EventBus and RxJava are different in their nature.
EventBus is just a bus as the name suggest - it provides the mechanism to subscribe and publish events to the "bus", without you caring how the wiring is done, what this "bus" actually is, etc. In the context of Android, the EventBus is just an easier way to deal with sending and receiving Broadcast messages with less boilerplate.
RxJava on the other hand is much much more powerful than that. Yes, you can subscribe and publish events, but you have far more control over the process - frequency, on which thread everything happens, etc. The main power of RxJava (in my opinion) is that you can manipulate the data being published very easy, using some of its tons of operators.
To sum up - if you only care about publishing some events and performing some actions when received - you'd probably be better off using the simplest of the two, namely some kind of Bus, or even plain old BroadcastReceivers. If you will also benefit of transforming the data, handling threading or simplified error handling - go for the RxJava approach. Just keep in mind that RxJava generally has a steep learning curve, so it takes some time to get used to its concept.
To understand RxJava, think of a list. Today manipulating a list like transforming, splitting, merging can be done easily using functional methods (map, groupBy, etc). RxJava uses the same principles except that its main target is not list but stream. Stream is asynchronous, often live data such as websocket channel or online movie.
Event bus comes from the needs to decouple classes which in Android are often bound with life cycle. Tight coupling of network callback and Activity's Views as an instance, has been a cause of numerous null pointer exceptions. Event bus with its publisher-subscriber pattern alleviates this issue.
How does it get mixed with RxJava ?
To begin RxJava incorporates Observable pattern. Here an Observer watches an Observable and reacts when an event arrives. Observable has several sub-classes, among which is Subject that has the properties of both Observable and Observer. Since it works by trapping an event and publishing it to subscribers, it technically functions as event bus.
Is it wise to use RxJava as event bus ? No. RxJava would introduce unnecessary complexities for simpler purposes. Only use it if the app does manipulate streams. For example pairing frames from a movie stream and subtitles from another stream. If the app simply consumes a REST API and needs to decouple the callback from activities/fragments then event bus is enough.
Live #Vesko wrote, RxJava and event bus differ in their nature and may serve to solve different problems. Nevertheless, there are some scenarios in which both of them can solve the same problem (although at different costs), and this might be the reason for why many people confuse these two concepts.
RxJava is conceptualy similar to Android LiveData that was released not so long ago, and to better understand these concepts, as well as event bus, I suggest you read my post. In the post I go over these very concepts, describing the scenarios in which we should use one over another and the pros and cons of using one rather than the other. I think it may be useful to you:
When and why to use LiveData
If you want to fetch data from sever and update UI, use RxJava + Refrofit. If update UI or do some operation without fetching data, EventBus is enough.
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){
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:
The components become loosely coupled by dependency on both event bus and specific event type
The coupling described in #1 above is not strong
The coupling described in #1 above is not evident
Event bus introduces performance overhead over simple callbacks
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:
Sending events from Service to Activity
Exchanging events between independent Fragments
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.
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 =)
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.
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.
Can I (is it correct to) use an event bus to communicate between UI views? For exemple, use it to communicate between Fragments instead of implementing a listener?
Can I use the same instance of the bus for more than one operation?
Thank you
Yes.
Otto was built exactly for that reason: to help you communicate fragments and activities aside without the need of serializing everything through Intents.
Also, for the instance question: You can reuse the bus wherever you want to. Sometimes, though, you would prefer to create different buses to separate groups of classes communicating: for example, in an MVP architecture, you would have a bus for each M-V-P group, or in another example, a bus for communicating with a specific service that is always running, etc.
This is a good example on how to use the library.
I am a huge fan of open source contributions square has done to the Android community and was looking into their latest contribution Otto (event bus )
http://square.github.io/otto/
Digging deeper I see that Otto uses reflection and there is no ordered broadcast ( a pattern where a unconsumed message is handed down from one receiver to the next receiver listening on the same type of event ) Otto believes in more of a fire and forget model .
Now android has LocalBroadcastManager (LBM ) in its v4 support library which serves the same purpose , though it's more bulkier and has more restrictions on the objects that are passed . But on the brighter side it does support ordered broadcast and its more akin to the normal broadcast.
Both Otto and LBM are within the same process space so in terms of speed I guess both would be same. The only real difference I could see is that Otto allows you to define custom events and you do not have to serialize/Parcel the Objects .
Hence my real question is when would you use Otto if LBM does the same things .
References :
http://nick.perfectedz.com/otto-event-system/
Using Intents or an event bus to communicate within the same app
https://plus.google.com/107049228697365395345/posts/6j4ANWngCUY
But on the brighter side it does support ordered broadcast
Not really. There is no sendOrderedBroadcast() on LocalBroadcastManager, and the priority on the IntentFilter does not appear to be used. If you mean "the broadcasts will be delivered in the order that I registered the receivers", that might be the current behavior, but there is no guarantee that it will stay that way.
Both Otto and LBM are within the same process space so in terms of speed i guess both would be same
They would be similar, though probably not identical.
Hence my real question is when would you use Otto if LBM does the same things
Comparing those two, Otto has a cleaner API, IMHO.
Personally, I'd use greenrobot's EventBus over either of those, because it offers more flexible threading models.
Both Otto and LBM are within the same process space so in terms of speed i guess both would be same .
I've found that registering Otto events are quite expensive, sometimes it takes more than 16 milliseconds to register event subscribers (That means you drop 1 FPS!). That's somewhat expected, as event subscribing in Otto is done by reflection.
While for LBM, it only takes a few hundred µs only for registering, which is almost 32x faster. (Result from traceview, Samsung Galaxy S4)
But of course, using Otto can write less code, there's a trade off.
otto makes code cleaner, smaller
otto makes testing easier