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.
Related
I'm a C/C++ guy, and I'm quite new to Java and Android.
So I'm creating a class instance in Activity "A" and I'm trying to use this instance to Activity "B". In C/C++ you would simply pass the address (pointer) of the instance.
Now I learned that with Android I should use a Parcel, but I don't get the idea: why would I want do all that parceling/deparceling procedure when all I want to do is passing a pointer?
Please enlighten me!
This is related to the Android activity model.
Since your app may be killed by the system to recover RAM (this should only happen when it's in the background, unless the system is in a really bad situation), an object reference just won't do. It'd be completely worthless once your process dies.
The intent you use to start activities is saved by the Activity Manager, so that it can be used to recreate your activity when the user navigates back to it. That's why all the data in your intent has to be parceled.
Keep in mind that this means that your two activities will have two similar instances -- but naturally, they will not be the same object, so changes to one won't be reflected in the other.
Parcel or parcalable is an efficient and alternative way to serialize objects in Android. Its an alternative to Serialization in core Java.
Java Serialization API allows us to convert an Object to stream that we can send over the network or save it as file or store in DB for later usage.
Its a way to exchange objects between sender and receiver(Class). Receiver than deserializes this object.
In Android parcel is used to exchange objects between different activities by using Intents.
java doesn't work like c/c++, you don't work directly with the memory. If you want to pass an object from A to B, you have to set it in a Bundle, and add that bundle to the intent. if it's a custom class, let's call it C, C should implement parcellable. Java works by value, not by reference.
custom parcelable objects
how do i pass data between activities?
I'm trying to send an object through an intent. From all the examples I've seen, it needs to be parcelable, and have all its sub-fields written to the parcel. Meaning that ultimately it is broken down to its ints, strings, etc. Is there a way to pass an object through an intent without all of this? Just send the object, have the receiving activity take it out of the intent, and then take whatever needed information it needs from it?
You might be able to get away with it, just by making the object serializable, but based on the object complexion, it could cause performance issues, other than that, there's no way to send a plain object the way you want, Intent bases its objects transfer on Inter Process Communication Protocol, which requires encode objects into more primitive values and send it to another end point and then decode them.
Hope this helps.
Regards!
You have to implement an interface called Parelable and write your object's instances inside a parcel.
Have a look at this tutorial
http://www.codexperience.co.za/post/passing-an-object-between-activities-using-an-intent
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 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).
Why is that the object has to be serialized or be Parcelable in order to be passed to an Intent ?
Intents can be sent between processes, so cannot contain Object:s limited to the current JVM.