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:
- What
Parcelable
is and why it’s used. - How to create a
Parcelable
class in Java. - 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
- Constructor(Parcel in): Reads the data back in the same order in which it was written.
- describeContents(): Typically returns 0 unless the Parcelable object includes a special file descriptor.
- writeToParcel(Parcel dest, int flags): Writes the object’s data into the
Parcel
. The order must match the reading order in the constructor. - 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
- Order Matters: The order of reading and writing in
writeToParcel
and the constructor fromParcel
must match. - 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 implementParcelable
), you’ll need to break it down further or find an alternative representation. - Use Android Studio’s Helper: In Android Studio, you can generate
Parcelable
boilerplate code by typingParcelable
then pressing Tab (if you have certain live templates installed) or by using the Generate action (Alt + Insert
orCommand + N
) and choosing Parcelable. - Performance:
Parcelable
is generally faster thanSerializable
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!