Recently an interviewer asked me a very tricky question. There are several parts of the question.
- Why (question is why and not how) do you need to parcel objects while sending from one activity to another and not send directly
Answer I gave -
Parcelable gives the capability to developers to restrict object creation which in a way makes it faster to use.
I was confused on the part, so decided to site difference between using serializable and parcelable :p (clever huuuhhh !), http://www.developerphil.com/parcelable-vs-serializable/ used this reference.
- While using Bundle, when we use String, int we do not need to parcel the data, so do you think the String/int is by default internally parcelled ?
Answer I gave -
because String/int is a primitive data-type, if we had used the Wrapper class directly, might be possible we had to use parcelable(I am not sure on that part)
I did not get any useful link after googling, also I or the interviewer is not quite satisfied with the answer. If you guys can help, would be wonderful !
Parcelling/serializing objects isn't for speed as you had guessed.
When you're sending data between Activities, and especially between different applications (remember that
Intent
objects aren't only meant for communication between your own Activities, but are also for between yours and those of other apps as well), you cannot expect the sender and the receiver to have access to the same memory address spaces.Android's documentation states that applications run in their own discrete memory spaces. Here's a quote to that effect from the docs:
So when you want to send an object
myObject
to some receivingActivity
, you can't send its reference/pointer because the receiver won't necessarily have access to the location specified by the pointer. Instead you'll have to send some representation ofmyObject
that the receiver can access and use -- this is why you need to marshall the data into a form that can be unmarshalled, and the easiest way to do so is to simply have the class of the object implementSerializable
which lets Java do its best to convert the object into an array of bytes that can be easily sent to and unmarshalled by the receiver. But sinceSerializable
uses reflection, this is slow.You can use other ways that are faster to marshall the data -- one, for example, is converting the object into its
JSON
representation using a library likeGson
and just sending it across since anyJSON
document can be represented as aString
and easily converted back to a JavaObject
. Another way, which is probably faster in pretty much all cases is using theParcelable
interface which lets you specify exactly how you want to marshall the data and exactly how it should be unmarshalled. It basically gives you more control on the transmission of the object.The tl:dr: Parcelling/Serializing etc is used because you can't send memory addresses across, so you have to send the actual data of the object and it has to be represented in some form.
How
Bundle
works internally is that it puts everything into aMap
and parcels/unparcels the data as needed (ie when get/put is called). For putting Objects into aBundle
, the object's class needs to implementSerializable
orParcelable
because it needs to tell theBundle
how it should be marshalled/unmarshalled internally.But primitive types and Strings are simple enough and used often enough that the developer doesn't need to specify how that needs to happen and
Bundle
provides convenience methods for it. I can't give you a solid answer at the lowest level of how they works because a lot of theParcel
code is natively implemented and I couldn't find it online, but they must certainly be straightforward to convert to their representation in bytes.