How to Pass Data Between Activities With Android Parcelable

Introduction

We often need to pass data between Activities of an Android app. An easy way to do this is with Intent.putExtra(), but if you have a lot of structured data to pass, Parcelable may be a better solution. In this post I’ll show you how Parcelable makes it easy to serialize classes for sharing between Activities.

Why Parcelable?

Parcelable is an Android-only Interface. It allows developers to serialize a class so its properties are easily transferred from one activity to another. This is done by reading and writing of objects from Parcels, which can contain flattened data inside message containers. 

Creating the Main Activity and Layout

Our main Activity will handle the collection of the book details. Let’s start by setting up our onCreate method.

package com.tutsplus.code.android.bookparcel;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //...
  }
}

Next, open activity_main.xml to set up the view’s layout and appearance. You will need two text entry fields and a button for submission.

It should look like this:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_margin="5dp"
    android:padding="5dp"
    tools:context="com.tutsplus.code.android.bookparcel.MainActivity">

    <EditText
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"
        android:padding="20dp"
        android:textSize="15sp"
        android:hint="Book Title"/>

    <EditText
        android:id="@+id/author"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"
        android:padding="20dp"
        android:textSize="15sp"
        android:hint="Book Author"/>

    <Button
        android:id="@+id/submit_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"
        android:text="Submit"/>

</LinearLayout>

Now open your main Activity and link the view fields to your activity. You’ll have to do it inside your onCreate() method, like this:

    //...

    final EditText mBkTitle = (EditText) findViewById(R.id.title);
    final EditText mBkAuthor = (EditText) findViewById(R.id.author);

    Button button = (Button) findViewById(R.id.submit_button);

To finish off MainActivity, you need to set up an onClickListener. This will be called whenever the Submit button is pressed. When that happens, the details entered are to be collected and sent to the next activity.

    
    button.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {

        Book book = new Book(mBkTitle.getText().toString(),
                mBkAuthor.getText().toString());

        Intent intent = new Intent(MainActivity.this, BookActivity.class);
        intent.putExtra("Book", book);
        startActivity(intent);
      }
    });

Here, you add an onClickListener to the Button instance you retrieved from your Activity layout. This code will be run whenever the Submit button is clicked. 

Note that we simply pass the Book instance to putExtra(). As we’ll see later, Parcelable takes care of serializing the book data to a string so it can be passed via the Intent.

Now that the main Activity is complete, we need to create our BookActivity as well as the Book class to hold book info.

Create the Book Class

Let’s create a Book class to hold info about each book.

public class Book implements Parcelable {
  // book basics
  private String title;
  private String author;
}

This class needs to implement Parcelable. This will enable the passing of the data from MainActivity to BookActivity.

We’ll also add some standard getter functions and a constructor to quickly create an instance of the class.

  // main constructor
  public Book(String title, String author) {
    this.title = title;
    this.author = author;
  }

  // getters
  public String getTitle() { return title; }
  public String getAuthor() { return author; }

Write to the Parcel

The writeToParcel method is where you add all your class data to the parcel. This is done in preparation for transfer. This method will be passed a Parcel instance which has a number of write methods that you can use to add each field to the parcel. Watch out: the order in which you write the data is important!

Here is how you do it.

  // write object values to parcel for storage
  public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(title);
    dest.writeString(author);
  }

Read Data Back From the Parcel

Just as the write method handles writing the data to be transferred, the constructor is used to read the transferred data back from the serialized Parcel. This method will be called on the receiving activity to collect the data.

Here’s how it should look:

  public Book(Parcel parcel) {
    title = parcel.readString();
    author = parcel.readString();
  }

The receiving Activity will get the data as a string, and will then call the getParcelableExtra method to start the process of collecting the data. That will trigger the constructor we defined above, which will deserialize the data and create a new Book instance. 

Parcelable.Creator

To complete your Parcelable class, you need to create a Parcelable.Creator instance and assign it to the CREATOR field. The Parcelable API will look for this field when it needs to deserialize an instance of your class that has been passed to another component.

 
  public static final Parcelable.Creator<Book> CREATOR = new Parcelable.Creator<Book>() {

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

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

This binds everything together. Its job is simple—it generates instances of your Parcelable class from a Parcel using the parcel data provided. The creator calls the constructor you defined above, passing it a Parcel object, and the constructor initializes the class attributes.

If your Parcelable class will have child classes, you’ll need to take some extra care with the describeContents() method. This will let you identify the specific child class that should be created by the Parcelable.Creator. You can read more about how this works on Stack Overflow.

Book Activity and Layout

Now we can complete our app with the book Activity. Go ahead and create a new empty activity called BookActivity. Make the layout look like what I have below.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_margin="5dp"
    android:padding="5dp"
    tools:context="com.tutsplus.code.android.bookparcel.BookActivity">

    <TextView
        android:id="@+id/bk_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="Book"
        android:textSize="30sp"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"
        android:padding="20dp"/>

    <TextView
        android:id="@+id/bk_author"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="Author"
        android:textSize="30sp"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"
        android:padding="20dp"/>

</LinearLayout>

In the activity_book.xml, you only need two TextView widgets, which will be used to show the title and author of the books.

Now let’s set up our activity. Your activity should already look like this:

package com.tutsplus.code.android.bookparcel;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class BookActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_book);


  }
}

In this activity, you want to receive the data that was passed from your main Activity and display it on your views. Thus you will retrieve the instances of your TextView using the id of the TextView set in your layout.

    TextView mBkTitle = (TextView) findViewById(R.id.bk_title);
    TextView mBkAuthor = (TextView) findViewById(R.id.bk_author);

Then, of course, you’ll call getIntent() because you will be retrieving data in this activity. The data you will be retrieving are collected from the Book class using getParcelableExtra(). Next, you set the values of the TextViews to the data you collected. Here is how it is done.

    Intent intent = getIntent();
    Book book = intent.getParcelableExtra("Book");

    mBkTitle.setText("Title:" + book.getTitle());
    mBkAuthor.setText("Author:" + book.getAuthor());

Build your application and launch it, and you should see the little beauty you have just built.

The completed app

Conclusion

In this post, you’ve seen how you can easily move objects from one activity to another. You no longer have to retrieve each data field you passed to the Intent object separately, and you don’t have to remember the name that you passed each field under. Not only that, but this process is faster than Java’s serialize functionality.

In this tutorial, you have learned how to use Parcelable to pass data from one activity to another. You can dive deeper into Parcelable by checking the official documentation

In the meantime, check out some of our other posts about Android app development!

Leave a Reply

Your email address will not be published. Required fields are marked *