Android Development
Android Activity
Data Transfer
Intent
Android Programming

How to send an object from one Android Activity to another using Intents?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Passing structured data between Android activities is common in navigation flows such as details screens, checkout flows, and profile editing. Intents can carry custom objects, but the object must be encoded in a form Android can marshal across process boundaries. This article covers the practical choice between Parcelable and Serializable, with Java examples and safety checks.

Core Sections

Choose Parcelable for App Performance

Android recommends Parcelable for frequent object passing because it avoids reflection-heavy serialization overhead. Serializable is simpler but often slower and can allocate more temporary objects.

Use Parcelable when:

  • object transfer is frequent
  • object size is moderate to large
  • performance on lower-end devices matters

Use Serializable for quick prototypes or very small low-frequency transfers.

Define a Parcelable Model in Java

java
1import android.os.Parcel;
2import android.os.Parcelable;
3
4public class UserProfile implements Parcelable {
5    private final long id;
6    private final String name;
7    private final String email;
8
9    public UserProfile(long id, String name, String email) {
10        this.id = id;
11        this.name = name;
12        this.email = email;
13    }
14
15    protected UserProfile(Parcel in) {
16        id = in.readLong();
17        name = in.readString();
18        email = in.readString();
19    }
20
21    public static final Creator<UserProfile> CREATOR = new Creator<UserProfile>() {
22        @Override
23        public UserProfile createFromParcel(Parcel in) {
24            return new UserProfile(in);
25        }
26
27        @Override
28        public UserProfile[] newArray(int size) {
29            return new UserProfile[size];
30        }
31    };
32
33    public long getId() { return id; }
34    public String getName() { return name; }
35    public String getEmail() { return email; }
36
37    @Override
38    public int describeContents() {
39        return 0;
40    }
41
42    @Override
43    public void writeToParcel(Parcel dest, int flags) {
44        dest.writeLong(id);
45        dest.writeString(name);
46        dest.writeString(email);
47    }
48}

Keep property order consistent between writeToParcel and parcel constructor.

Send the Object with Intent Extras

java
1Intent intent = new Intent(CurrentActivity.this, ProfileActivity.class);
2UserProfile profile = new UserProfile(7L, "Ava", "[email protected]");
3intent.putExtra("extra_user_profile", profile);
4startActivity(intent);

Use explicit constant keys to avoid typo bugs.

java
public static final String EXTRA_USER_PROFILE = "extra_user_profile";

Receive the Object Safely

In the destination activity, read the value and handle nulls defensively.

java
1UserProfile profile = getIntent().getParcelableExtra("extra_user_profile");
2if (profile == null) {
3    finish();
4    return;
5}
6
7TextView nameView = findViewById(R.id.nameText);
8nameView.setText(profile.getName());

Null handling is important because activities can be launched from multiple paths.

Passing Lists of Objects

If you need multiple models, pass an ArrayList of parcelables.

java
1ArrayList<UserProfile> users = new ArrayList<>();
2users.add(new UserProfile(1L, "Ava", "[email protected]"));
3users.add(new UserProfile(2L, "Leo", "[email protected]"));
4
5Intent intent = new Intent(this, UserListActivity.class);
6intent.putParcelableArrayListExtra("extra_users", users);
7startActivity(intent);

Receive in destination:

java
ArrayList<UserProfile> users = getIntent().getParcelableArrayListExtra("extra_users");
if (users == null) users = new ArrayList<>();

Size and Lifecycle Considerations

Intent extras are not designed for large payloads. If your object graph is large, pass an ID and fetch data from:

  • Room database
  • repository cache
  • network layer

This keeps navigation robust and avoids binder transaction-size issues.

Also consider process recreation. Persist required identifiers in savedInstanceState so you can recover after configuration change or process death.

Quick Test Strategy

Instrumented test ideas:

  1. launch destination with valid parcelable and assert UI fields
  2. launch without extra and verify fallback behavior
  3. launch with edge values such as empty strings

These tests catch regressions when model fields change.

Common Pitfalls

  • Using Serializable for high-frequency transfers and then hitting avoidable UI lag.
  • Mismatching parcel read and write order, which corrupts deserialized values.
  • Hardcoding extra keys in multiple places, causing typo-related nulls.
  • Sending large object graphs in extras instead of passing stable identifiers.
  • Skipping null checks when reading extras in destination activities.

Summary

  • Use Parcelable as the default for passing custom objects between Android activities.
  • Keep parcel serialization order consistent and centralize extra keys.
  • Read extras defensively and support alternate launch paths.
  • Pass IDs, not large payloads, when data size grows.
  • Add focused tests to protect navigation data contracts as models evolve.

Course illustration
Course illustration

All Rights Reserved.