Android Java: Using Parcelable to Pass Objects Between Activities

Md Tayobur Rahman · 27 Jan, 2025
Thumbnail for Android Java: Using Parcelable to Pass Objects Between Activities

Android Java: Using Parcelable to Pass Objects Between Activities

Passing objects between Android activities can be done efficiently using the Parcelable interface. By implementing Parcelable in your custom class, you explicitly define how the object’s data is written to and restored from a Parcel.


Android Java: Using Parcelable to Pass Objects Between Activities

In Android development, it’s common to need to pass custom objects between Activities. One way to do this efficiently is by making your objects Parcelable. This mechanism is faster and more optimized for Android than the older Serializable approach. In this blog post, we’ll go through:

  1. What Parcelable is and why it’s used.
  2. How to create a Parcelable class in Java.
  3. How to pass this parcelable object from one Activity to another.

1. What is Parcelable?

Parcelable is an Android-specific interface designed to serialize and deserialize objects. It’s optimized for Inter-Process Communication (IPC) in Android, making it typically faster than the Java Serializable interface. By implementing Parcelable, you define exactly how your object is broken down (marshaled) and reassembled (unmarshaled), which leads to better performance compared to reflection-based serialization.

2. Creating a Parcelable Class in Java

Let’s say we want to send a custom User object between Activities. Our User class might look like this:

package com.example.myapp;

import android.os.Parcel;
import android.os.Parcelable;

public class User implements Parcelable {
    private String name;
    private int age;

    // Constructor
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Getter methods
    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    /**
     * 1) Constructor that takes a Parcel and gives you back a populated object
     */
    protected User(Parcel in) {
        // Read in the same order you write in writeToParcel
        name = in.readString();
        age = in.readInt();
    }

    /**
     * 2) Describe the kinds of special objects contained in this Parcelable’s marshalled representation.
     * For most cases, return 0.
     */
    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * 3) Flatten/serialize the object into the Parcel
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        // Write in the same order you will read in the constructor
        dest.writeString(name);
        dest.writeInt(age);
    }

    /**
     * 4) A public CREATOR field that generates instances of your Parcelable class
     */
    public static final Creator<User> CREATOR = new Creator<User>() {
        @Override
        public User createFromParcel(Parcel in) {
            return new User(in);
        }

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

Steps Explained

  1. Constructor(Parcel in): Reads the data back in the same order in which it was written.
  2. describeContents(): Typically returns 0 unless the Parcelable object includes a special file descriptor.
  3. writeToParcel(Parcel dest, int flags): Writes the object’s data into the Parcel. The order must match the reading order in the constructor.
  4. CREATOR: A Parcelable.Creator that generates instances of your class from a Parcel.

3. Passing the Parcelable Object Between Activities

3.1 Sending the Object

Assume you are in MainActivity and want to open DetailActivity, passing the User object:

// MainActivity.java
package com.example.myapp;

import android.content.Intent;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Prepare our User object
        User user = new User("Alice", 25);

        // Create an Intent to start DetailActivity
        Intent intent = new Intent(MainActivity.this, DetailActivity.class);
        
        // Put the User object in the Intent
        intent.putExtra("USER_DATA", user);

        // Start the DetailActivity
        startActivity(intent);

        // (In a real app you would setContentView, handle UI, etc.)
    }
}

Here, the User object is being put into the Intent as a Parcelable via putExtra(String key, Parcelable value).

3.2 Receiving the Object

In the receiving Activity (DetailActivity), you can retrieve the User object in onCreate:

// DetailActivity.java
package com.example.myapp;

import android.os.Bundle;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;

public class DetailActivity extends AppCompatActivity {

    private TextView textViewUserDetails;

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

        textViewUserDetails = findViewById(R.id.textViewUserDetails);

        // Retrieve the Parcelable object
        User user = getIntent().getParcelableExtra("USER_DATA");
        if (user != null) {
            String userDetails = "Name: " + user.getName() + "\nAge: " + user.getAge();
            textViewUserDetails.setText(userDetails);
        }
    }
}

The call to getParcelableExtra("USER_DATA") will automatically reconstruct your User object using the CREATOR you defined.

Best Practices and Tips

  1. Order Matters: The order of reading and writing in writeToParcel and the constructor from Parcel must match.
  2. Avoid Non-Parcelable Fields: If a field can’t be represented in a Parcel (like a complex object or a non-primitive that doesn’t implement Parcelable), you’ll need to break it down further or find an alternative representation.
  3. Use Android Studio’s Helper: In Android Studio, you can generate Parcelable boilerplate code by typing Parcelable then pressing Tab (if you have certain live templates installed) or by using the Generate action (Alt + Insert or Command + N) and choosing Parcelable.
  4. Performance: Parcelable is generally faster than Serializable because it doesn’t rely on reflection, which reduces overhead.

Conclusion

Using Parcelable in Android is a neat solution for passing complex data objects between different components of your application (such as Activities and Fragments). It’s quite straightforward once you understand how the parceling and unparceling process works. Implementing Parcelable correctly will help you make efficient and clean data transfers, especially when your app grows in complexity.

Now that you’ve learned how to implement a parcelable class and pass the object around, go ahead and use it in your projects. It’s one of those Android fundamentals that quickly pays off once you adopt it in your workflows!

Happy Coding!

Related Posts

Understanding Java Access Modifiers: A Comprehensive Guide
Understanding Java Access Modifiers: A Comprehensive Guide

Unlock the secrets of Java access modifiers with our in-depth guide. Learn how t...

Read More