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
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 just want to check if there may be a simpler way to do this.
If I have some generic ASyncTask and it's done I want to pass a success boolean back to the original caller. Normally I create an interface inside the custom AsyncTask class with just one method void onSuccess(boolean success);
The caller would implement that and so on.
I just feel that it clutters the project with mini interfaces.
I could also pass along a handler, but I would have to create a handler for only that purpose which often feels like "just a bit too much code for the purpose".
I could pass a runnable along, but I would have to fire it on a thread and that could cause trouble.
What I want I to execute a method of the calling object when the asynctask has finished. In Objective C I can pass along a "block" of code and maybe there is something similar in Android.
It is a theoretical question and there is no urgency, just curiosity.
You can incorporate event bus into your app, like GreenRobot's EventBus, OTTO or other available but this still requires some work. I personally still do not see problems creating Interfaces and stuff whenever it makes sense for my project.
The first thing I think of is lambdas but since Android doesn't support Java 8 that might be a problem.
If you just need the lambdas and not the other new things in Java 8 you can have a look here:
https://hakanyamanyar.wordpress.com/2014/07/08/using-java-8-lambda-expressions-in-android-developer-tools/
He is basically using a gradle dependency called gradle-retrolambda that allows you to use lambdas in Android. I have not tried this my self though.
Other things that might work for your use case except using Interfaces might be EventBus or Square.io's Otto. They are both based on an publish/subscribe event pattern. I've tried EventBus my self and it's very easy to use and works well.
If I send a Parcelable object to another part of my program via LocalBroadcastManager -is the Parcelable immutable then? Immutable in the sense that the received Parcelable cant affect the object that was originally transmitted. I would guess so, because I guess Parcelable is a "deepcopy" serialization mechanism and not pass by reference, but I need to be sure. Can someone who knows, tell me if I have to worry about someone in the receiving end changing values on the received object, if I want to prevent that from affecting the original object...?
If I send a Parcelable object to another part of my program via LocalBroadcastManager -is the Parcelable immutable then?
That is not guaranteed. In fact, AFAIK, it does not happen at all for local broadcasts.
I guess Parcelable is a "deepcopy" serialization mechanism and not pass by reference
Only across process boundaries. That happens to include things like startActivity() for another one of your activities, because those involve IPC. But the Intent object -- and its extras -- is simply passed around your process with LocalBroadcastManager. I see no place where Intent would be forced to make a copy.
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.
I know this question has been asked multiple number of times and i have been through a lot of these questions......almost all of these questions throw up the use of the parcelable interface for your class.
However in a couple of questions i came across a quotation:
"NOTE: Seeing Parcelable might have triggered the question, why is Android not using the
built-in Java serialization mechanism? It turns out that the Android team came to the conclusion
that the serialization in Java is far too slow to satisfy Android’s interprocess-communication
requirements. So the team built the Parcelable solution. The Parcelable approach requires
that you explicitly serialize the members of your class, but in the end, you get a much faster
serialization of your objects.
Also realize that Android provides two mechanisms that allow you to pass data to another
process. The first is to pass a bundle to an activity using an intent, and the second is to pass a
Parcelable to a service. These two mechanisms are not interchangeable and should not be
confused. That is, the Parcelable is not meant to be passed to an activity. If you want to start
an activity and pass it some data, use a bundle. Parcelable is meant to be used only as part of
an AIDL definition."
This quote can also be found in the book Pro Android 2.
Now seeing that all activities within the same application run in the same process(Every Activity in Android is a Process,or One Application is one process),unless otherwise specified in the manifest,communication within the activities of the same application is not Interprocess communication per se.So is it really faster to use the parcelable class or is it just enough to pass your object attributes through bundle via intent ?
Shedding any light on this aspect will be largely appreciated.
Cheers !!
There's a FAQ for that. :)
The short answer is that the Android team recommends three techniques for passing data between activities and services within an app: a singleton class; a public static field or method; a HashMap of WeakReferences to Objects (and you pass the key in the intent). The major issue to keep in mind is how your data is going to behave under various lifecycle events. (For instance, if the user turns the phone, by default your activities will be destroyed and recreated; your data handling method needs to be designed with that in mind.)
The Parcelable construct is designed to be very fast at passing data across application memory boundaries: within an application you are MUCH better served using Bundle because all the memory locations the data is stored in are accessible to both the sender and the receiver. Since the in-memory objects are accessible there is no need to incur the cost of reconstruction: just use the Bundle, which is really just a glorified HashMap with type-specific put/get methods.
For AIDL and IPC purposes you can't (by default) share memory locations so you need an efficient way of moving data: this is where Parcelable kicks in. Unless one of the components of your application is using the remote process capability then there is no need to use Parcelable.
From docs:
Parcelables
The Parcelable protocol provides an extremely efficient (but
low-level) protocol for objects to write and read themselves from
Parcels. You can use the direct methods writeParcelable(Parcelable,
int) and readParcelable(ClassLoader) or writeParcelableArray(T[], int)
and readParcelableArray(ClassLoader) to write or read. These methods
write both the class type and its data to the Parcel, allowing that
class to be reconstructed from the appropriate class loader when later
reading.
There are also some methods that provide a more efficient way to work
with Parcelables: writeTypedArray(T[], int), writeTypedList(List),
readTypedArray(T[], Parcelable.Creator) and readTypedList(List,
Parcelable.Creator). These methods do not write the class information
of the original object: instead, the caller of the read function must
know what type to expect and pass in the appropriate
Parcelable.Creator instead to properly construct the new object and
read its data. (To more efficient write and read a single Parceable
object, you can directly call Parcelable.writeToParcel and
Parcelable.Creator.createFromParcel yourself.)
Bundles
A special type-safe container, called Bundle, is available for
key/value maps of heterogeneous values. This has many optimizations
for improved performance when reading and writing data, and its
type-safe API avoids difficult to debug type errors when finally
marshalling the data contents into a Parcel. The methods to use are
writeBundle(Bundle), readBundle(), and readBundle(ClassLoader).