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.
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.
I have implemented a service, where I handle the state changes(connect, disconnect, onServiceDiscoverd, onCharacteristicChange etc) and receiving data from another device through gatt Server.
My question is, Can the events be handled efficiently using Greenrobot Eventbus replacing broadcast receiver between service and Activity?
Unlike LocalBroadcastManager, EventBus is more simple to use. You only go via 3 steps:
1- Create an event class. A simple Java class that represent the response when
the action occur.
2- Register the event bus as a subscriber in your Activity onCreate method
EventBus.getDefault().register(this);
And of course, unregister it in your Activity onDestroy method
EventBus.getDefault().unregister(this);
3- The subscribing method is created in the same activity that registered for the EventBus. Example in WorkOrderActivity
#Subscribe
public void onEvent(EventClass event)
When the event occur, you should call the post method, passing the event object you created before.
EventBus.getDefault().post(new EventClass (Data));
As kmaini mentioned, you can replace it with LocalBroadcastManager, but you will have to map the data from the intent by yourself. Unlike EventBus which can pass objects.
Also, greenrobot, the creators of EventBus Library, answered this question here:
Q: How's EventBus different to Android's BroadcastReceiver/Intent
system?
A: 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.
From another perspective, I believe broadcast managers in Android uses main thread handler's message queue to process events. So, if you are free to use a different thread (if you have no-UI events/jobs/tasks) with a proper queue (like using another HandlerThread) then you can take advantage of using that thread's specific queue to process your jobs, without interfering UI events and mixing your stuff with UI work. You can also play with the thread's priority value to balance the work.
Now, if GreenRobot provides that all functionality in a few lines of code, then I would definitely try it to see any performance gain.
EventBus makes things much easier because you can pass is arbitrary Java objects along in the event.You not do the same with Intents because your object has to implement Parcelable and the "tedious" parcelable implementation which is something you might not what to do on an existing code base.
Has anyone really used this? I am so in the habit of registering/unregistering my BroadcastReceivers inside an Activity that I almost stuttered when I saw this. Does this keep all my Broadcasts to my specific Linux Process ID that my app is running on? My Actions and Extras are package specific and the ones that are not are meant to be that way to allow other applications to possibly pick up an intent. I can see one easy use, I just did a test case with an AsyncTask, ProgressDialog, and an Activity. But what is the purpose? Is this for security? I am not a linux guru and was hoping for some input.
Per the LocalBroadcastManager documentation, the advantages are:
You know that the data you are broadcasting won't leave your app, so don't need to worry about leaking private data.
It is not possible for other applications to send these broadcasts to your app, so you don't need to worry about having security holes they can exploit.
It is more efficient than sending a global broadcast through the system.
You can also take a look at the LocalBroadcastManager source if you'd like to determine exactly how it works.
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
I know that an activity can communicate with a local service using the IBinder interface; I am trying to find a way for communication between two services.
Specifically, I have my main service starting an IntentService to handle file uploads. I want this IntentService to inform back to the main service once it is done uploading, and before it dies.
Any ideas about how this would happen?
You have to use BroadcastReceiver to receive intents, and when you want to communicate simply make an Intent with appropriate values.
This way you should be able to make a 2-way communication between any component.
In Android, there is a special way of completing tasks like yours. Look at AIDL (it's not well documented in official docs, but there are some extra sources on the web). This is a way of implementing two-way communication between any components placed in separate processes. In comparison to BroadcastReceivers, using this you'd get direct calls and callbacks, that will be less dirty than relying on something would come from somewhere in BroadcastReceiver.
To reach the needed effect, you'll have to define an interface for a callback and an interface for performing actions (with a callback supplied, or register/unregister methods). Than, after you received some command using the second interface, you should perform the job and post back the result through callback. To reach the asynchronous completion add a key work "oneway" before method signature (return type). To separate in and out params (if you need it), use "in", "out" and "inout" keywords near params.
As it comes to restrictions, only primitives, arrays and parcelables (and parcelable arrays) might be transferred between processes.
To control your callbacks lifecycle and operations atomicity, use RemoteCallbacksList for storing registered callbacks and notifying recipients using the duplicate of your list got from beginBroadcast.
If you have any troubles, you're free to ask here.