How to use Android Parcelable to pass Objects between Activities

By     |   Feb 08, 2017   |   Post Comments

android parcelable

Android as a mobile platform, is more memory constrained. So mobile app developers are pushed to write code that consumes less memory without compromising on performance. Even though Java provides several ways to accomplish works, it sometimes comes with lot of memory usage.

For example, unlike integers and strings, you can’t pass objects between activities. For this, you have to flatten the data.

There are two options available: Java’s Serializable interface and Android’s Parcelable interface. Which is better? We’ll look at each of them.

Serializable is a java marker interface with no methods, which helps serialize and deserialize Objects. Actually, ObjectInputStream and ObjectOutputStream are the classes that serialize the Object into a stream and deserialize back into an Object. The class that implements Serializable are meant to be serialized.

Since the User class implements Serializable, when we pass it between Activities using Bundle, the class gets serialized into a stream and in the receiver Activity it gets deserialized back into User.

The putExtra method serializes the User class into a stream and getSerializableExtra deserializes the stream into User.

Even Though it looks easy to implement this, there are some memory issues associated if the Object class stores lots of data. This serialization process creates a lot of temporary objects and since it also uses reflection, this process tends to be slow and causes more Garbage Collection.

A better way to do this is using Android’s Parcelable interface. It is an interface used to marshal and unmarshal Objects in Android. The main advantage of using Parcelable is it requires us to explicitly serialize the Objects, so there is no reflection involved and less garbage collection. It is said that Parcelable takes on the order of 10x less time to both serialize and deserialize, compared to Serializable.

To use Parcelable, just implement the interface and override the writeToParcel method. In this method, you explicitly write the data to Parcel, which is a container for all the data. You must also implement a non-null static field called CREATOR of type that implements the interface Parcelable.Creator.

A typical example of the User class is shown below:

As you can see we override the writeToParcel method to write the name and age to Parcel. This way the User is flattened. To deserialize, the CREATOR field’s createFromParcel returns a new instance of the Parcelable object, by initializing the variables from the Parcel.

Note that the values should be read from the Parcel in the same order they are written into it using writeToParcel.

To write an Arraylist of Objects into parcel, you can use parcel.writeList(objectName);
To read the ArrayList, use parcel.readArrayList(classLoader);

The main disadvantage is that you have to write all the boilerplate code yourself. But there are libraries you can use to make it easy. Parceler is such library that uses annotations to reduce boilerplate. Typically, to make a class Parcelable using this library, just add @Parcel to the class.

To pass the Object use

intent.putExtra("user", Parcels.wrap(user));

and to get the Object use

User user = Parcels.unwrap(getIntent().getParcelableExtra("user"));

You can find a demo of manually implementing Parcelable on my github page