Transfer Data between Activities with Android Parcelable

Share this article

Transfer Data between Activities with Android Parcelable

An Android app typically consists of more than one activity that need to pass data between each other. For example a primary activity with a list of elements and a corresponding secondary activity to show the details of these elements. To move from one activity to another you use the intent class to connect them together. This lets you launch an activity and optionally return later (If you’re new to intents there’s a good resource in the Google dev docs that explains the process)

Part of the process is sending data between activities and you do that via the putExtra and getExtra methods of our intent object. The idea is to make the process of passing different types of data easy as:

//Inside first activity
Intent intent = new Intent(MainActivity.this, DetailActivity.class);
intent.putExtra("name", "John Smith");
intent.putExtra("age", 26);

//inside second activity
Intent intent = getIntent();
String suburb = intent.getStringExtra("name");
Integer age = intent.getIntExtra("age");

This works well for basic data types such as string, bool, and Integer but doesn’t work for objects. What should you do when you want to pass an object and its data from one activity to the other? You use the parcelableinterface

Introducing the Parcelable Interface

Since objects can contain any number of mixed data types you can’t use putExtra to move values across. Java has had the ability to serialize objects for a while, but it’s a slow process as the system needs to perform heavy lifting to move the data. Parcelable is an Android only Interface used to serialize a class so its properties can be transferred from one activity to another.

Implementing Parcelable

The Parcelable interface adds methods to all classes you want to be able to transfer between activities. These methods are how parcelable deconstructs the object in one activity and reconstructs it in another.

For this example you’ll look at how to implement parcelable in a simple class. I used this class in one of my previous articles where I created a property listing and a corresponding detail activity. The idea is that when you select a property in the list view you’re taken to an expanded detail view to find out more info.

Example Screens

Creating the Property Class

First create a class to hold info about each property. Start by adding the following into a new class file in your project.

public class Property implements {
    //property basics
    private int streetNumber;
    private String streetName;
    private String suburb;
    private String state;
    private String description;
    private String image;
    private Double price;
    private int bedrooms;
    private int bathrooms;
    private int carspots;
    private Boolean featured;

    //main constructor
    public Property(int streetNumber, String streetName, String suburb, String state, String description, Double price, String image, int bedrooms, int bathrooms, int carspots, Boolean featured){

        this.streetNumber = streetNumber;
        this.streetName = streetName;
        this.suburb = suburb;
        this.state = state;
        this.description = description;
        this.price = price;
        this.image = image;
        this.bedrooms = bedrooms;
        this.bathrooms = bathrooms;
        this.carspots = carspots;
        this.featured = featured;
    }


    //getters
    public int getStreetNumber() { return streetNumber; }
    public String getStreetName() {return streetName; }
    public String getSuburb() {return suburb; }
    public String getState() {return state; }
    public String getDescription() {return description; }
    public Double getPrice() {return price; }
    public String getImage() { return image; }
    public int getBedrooms(){ return bedrooms; }
    public int getBathrooms(){ return bathrooms; }
    public int getCarspots(){ return carspots; }
    public Boolean getFeatured(){return featured; }
}

The class contains a series of properties, getter functions and a constructor to create a single object of the class.

Add the Parcelable Interface

Here’s the main part, implementing the interface. Change the declaration of the class as follows:

public class Property implements Parcelable {
  ...
}

Add the following methods inside the class. I’ll run through how they work shortly.

//write object values to parcel for storage
public void writeToParcel(Parcel dest, int flags){
    //write all properties to the parcle
}

//constructor used for parcel
public Property(Parcel parcel){
    //read and set saved values from parcel
}

//creator - used when un-parceling our parcle (creating the object)
public static final Parcelable.Creator<Property> CREATOR = new Parcelable.Creator<Property>(){

    @Override
    public Property createFromParcel(Parcel parcel) {
        return new Property(parcel);
    }

    @Override
    public Property[] newArray(int size) {
        return new Property[0];
    }
};

//return hashcode of object
public int describeContents() {
    return hashCode();
}

Parcelable needs this code to function. It handles the process of copying your object data into a parcel for transmission between activities and then re-creating the object on the other side.

Let’s break down how this all works.

Writing Method – writeToParcel

In this method you add all your class properties to the parcel in preparation for transfer. You use each of the write methods to add each of your properties.

//write object values to parcel for storage
public void writeToParcel(Parcel dest, int flags){
    dest.writeString(streetName);
    dest.writeString(suburb);
    dest.writeString(state);
    dest.writeString(description);
    dest.writeString(image);
    dest.writeInt(streetNumber);
    dest.writeValue(featured);
    dest.writeDouble(price);
    dest.writeInt(bedrooms);
    dest.writeInt(bathrooms);
    dest.writeInt(carspots);
}

Notes:

  • The order in which you write these values is important. When collecting these values later you will need to collect them in the same order.
  • If you’re going to send boolean values (for example the featured property). You will have to use writeValue and then force cast it to a boolean on the other side as there is no native method for adding booleans.

Reading Method – Property

This method is the constructor, called on the receiving activity, where you will be collecting values.

When the secondary activity calls the getParcelableExtra method of the intent object to start the process. This constructor is where you collect the values and set up the properties of the object:

//constructor used for parcel
public Property(Parcel parcel){
    streetName = parcel.readString();
    suburb = parcel.readString();
    state = parcel.readString();
    description = parcel.readString();
    image = parcel.readString();
    streetNumber = parcel.readInt();
    featured = (Boolean) parcel.readValue(null);
    price = parcel.readDouble();
    bedrooms = parcel.readInt();
    bathrooms = parcel.readInt();
    carspots = parcel.readInt();
}

At this point you’ve populated the object with data.

If you are using your own object then the name of this function will match the name of your own class e.g person, animal, place, the name has to match the class name.

The Creator Method

Parcelable requires this method to bind everything together. There’s little you need to do here as the createFromParcel method will return your newly populated object.

//used when un-parceling our parcel (creating the object)
public static final Parcelable.Creator<Property> CREATOR = new Parcelable.Creator<Property>(){

    @Override
    public Property createFromParcel(Parcel parcel) {
        return new Property(parcel);
    }

    @Override
    public Property[] newArray(int size) {
        return new Property[0];
    }
};

Other methods – describeContents

This method doesn’t do much.

//return hashcode of object
public int describeContents() {
    return hashCode();
}

Starting the Intent in the First Activity

Inside the first activity create your intent object and use the putExtra method to add the whole class as an extra. This will only work if you’ve implemented the Parcelable interface correctly (as it’s at this point parcelable starts serializing your object).

Intent intent = new Intent(MainActivity.this, DetailActivity.class);
intent.putExtra("Property", property);
startActivity(intent);

If this works, the new activity will open. You will need to ensure the activity is added to your manifest file.

Collecting Values in the Secondary Activity

Now that you’re in the second activity you need to collect the intent object and extract the property class that’s been converted into a parcel. Once you’ve done this you can call the standard methods to get the data like property name, price and description.

//collect our intent
Intent intent = getIntent();
Property property = intent.getParcelableExtra("Property");

//now collect all property values
String streetName = property.getStreetName();
Integer streetNumber = property.getStreetNumber();
String suburb = property.getSuburb();
String state = property.getState();
String description = property.getDescription();
Double price = property.getPrice();
Integer bedrooms = property.getBedrooms();
Integer bathrooms = property.getBathrooms();
Integer carspots = property.getCarspots();
String image = property.getImage();
Integer imageID = this.getResources().getIdentifier(image, "drawable", this.getPackageName());
String address = streetNumber + " " + streetName + ", " + suburb + ", " + state;

Pass the Parcel

As you have see, there’s work involved in getting parcelable up and running, but once it all works the payoff is worth it.

You can move entire objects from one activity to another, retaining all class methods and abilities. This is great if you have a complex method that transforms your data.

You no longer have to remember the different names which you would normally pass to the intent object as extra data, e.g String streetName = intent.getStringExtra("streetName");. You can get your object and move on.

The process is fast and optimized. Doing it this way is faster than using Java’s serialize functionality as you implicitly tell it how to save and extract your data.

Please let me know if you have any comments or questions.

Frequently Asked Questions (FAQs) about Android Parcelable

What is the main purpose of Parcelable in Android?

Parcelable in Android is an interface that allows you to serialize a class so that it can be passed around via an Intent or a Bundle. It’s a fast IPC (Inter-Process Communication) transport. When you need to send data from one activity to another, Parcelable is used to marshall and unmarshall the data, so it can be recreated in another process. This is particularly useful when you want to pass custom objects between activities or fragments.

How does Parcelable compare to Java Serializable?

Parcelable is specifically designed for Android and is said to be faster than Java’s native Serializable interface. While Serializable uses reflection to perform operations, which is a slow process, Parcelable allows developers to explicitly define the serialization process, making it more efficient. However, Parcelable requires more effort to implement than Serializable.

How do I implement Parcelable in my Android application?

To implement Parcelable, your class must implement the Parcelable interface and the static Parcelable.Creator interface. You’ll need to override the describeContents() and writeToParcel() methods from the Parcelable interface. The Creator contains methods to create new instances of your Parcelable class, as well as a newArray() method that creates an array of your Parcelable class.

Can I pass complex objects between activities using Parcelable?

Yes, Parcelable can handle complex objects. If your class has non-primitive data types, those classes should also implement Parcelable. This way, you can write and read these objects to and from the Parcel.

What is the role of the writeToParcel() method in Parcelable?

The writeToParcel() method is where you write each field in your object to the Parcel. You need to ensure that you write and read the fields in the same order. This method is called when we flatten the object into a Parcel.

What is the function of the describeContents() method in Parcelable?

The describeContents() method is used to describe any special kind of object that might be included in the Parcelable instance. Most commonly, it returns 0, unless your class involves a FileDescriptor.

What is the Parcelable.Creator and why is it important?

Parcelable.Creator is an interface that must be implemented and provided as a public static final field called CREATOR in your class. It generates instances of your Parcelable class from a Parcel. It’s essential for unmarshalling data stored in a Parcel.

Can I use Parcelable to save data across application instances?

Parcelable is not recommended for persisting data or saving data across application instances. It’s primarily used for short-term storage and for passing data between components. For long-term storage, consider using databases or shared preferences.

Is Parcelable suitable for large data sets?

Parcelable is efficient, but it’s not designed to handle extremely large data sets. For large amounts of data, consider using alternatives like a database or a file storage system.

Can I use Parcelable with Kotlin?

Yes, you can use Parcelable with Kotlin. In fact, Kotlin provides the @Parcelize annotation, which automates much of the process, making it easier to implement Parcelable in your Kotlin classes.

Simon CodringtonSimon Codrington
View Author

Full stack developer and overall web enthusiast. I love everything to do with web / design and my passion revolves around creating awesome websites. Focusing primarily on WordPress, I create themes, plugins and bespoke solutions.

architecturechriswjava
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week