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.
Related
A library that I am using has an Android activity. I would like to pass a callback to the activity to get notified of certain user events like when user enters a specific code or draws something on the screen. I am not able to find a way to pass callbacks to the android activity.
Note: I can edit the library, however, I prefer to leave the activity within the library for architectural reasons and ease of testing without integrating with the larger app.
What is the best possible way to solve this? Are there any Android design patterns?
What is the best possible way to solve this?
Modify the activity to post an event on an event bus (greenrobot's EventBus, Square's Otto, LocalBroadcastManager when these things occur. Then, listen for those events elsewhere in your app.
I prefer to leave the activity within the library for architectural reasons and ease of testing without integrating with the larger app
Then convince the developer of the library to modify the activity to post an event on an event bus (greenrobot's EventBus, Square's Otto, LocalBroadcastManager when these things occur. Then, listen for those events elsewhere in your app.
Or, convince the developer to offer some other means of accomplishing this (e.g., you subclass the activity and override certain methods to be notified of these events).
It sounds like you have access to the library src code, so create an AIDL interface for communication between your app and the lib. You can set up a callback via AIDL and have the lib send your app the data in real-time as it gets generated.
There's quite a bit of code involved but it is achievable. You can start here:
https://developer.android.com/guide/components/aidl
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.
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
I understand that while android allows Serializable objects to be passed within Intents, it's not recommended for performance reasons.
however, if one is using LocalBroadcastManager, does the object ever get serialized, or parceled at all when passed in an intent? since LBM is not inter-process, there'd be no reason to invoke serialization (or parceling for that matter).
You are right, there should be no reason to invoke serialization or parceling when using LocalBroadcastManager, however, that class was designed as a replacement for the normal BroadcastManager in cases in which sending a broadcast through the system made no sense; I think the idea was to make it possible for devs to replace normal broadcast with local ones w/out too much effort.
If you are working on a new project and need this kind of functionality, I would recommend to use a bus library like Otto or EventBus, which solves the same problem in a better, more elegant way (IMHO).
A quick glance at LocalBroadcastManager's source-code would suggest that Serializable/Parcelable objects in Intents are not serialized or parceled.
https://android.googlesource.com/platform/frameworks/support/+/refs/heads/master/v4/java/android/support/v4/content/LocalBroadcastManager.java
Android's compatibility pack supports LocalBroadcastManager, which enables sending broadcasts within my process.
http://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html
Until now I was using callbacks (Interfaces similar to OnClickListener) to transfer data (asynchronous and synchronous) between different parts of my apps.
I was wondering if one is better then the other.
Any opinions?
LocalBroadcastManager lets you use Intent's and IntentFilter's so its easier to migrate from system-wide broadcasts to local ones. It also has some queuing code and might be more reliable than your own code (or not, depending how sophisticated your implementation is). Other than that, it essentially just keeps lists of receivers in memory and iterates them to find a match.
Another, alternative is to use an event bus such as Square's Otto (based on Guava), which adds type safety and is just as efficient.
As far I've known, LocalBroadcastManager works like a charm. It's hassle free and you can pass any argument within Intent and retrieve it back during Listening. The only reliability is the broadcast manager puts intent into queue.
When should you use LocalBroadCastManager?
When you have single activity (FragmentActivity) and tons of Fragment classes, then it's easier to have a localBroadcastManager within the Single Activity.
If you have a lot of Activities then using this may be helpful, but also keep in mind that you are already using intents to launch new activities, so if there is any pending intent then, this Broadcast will be in Queue and you will need to wait.
So, the best use is Single Activity with numerous Fragments.