Transferring data between screens (Activities) is a central part of Android app development. Whether you’re sending user input, object models, or simple flags, you need reliable and efficient techniques to pass data from one Activity to another.
This guide covers:
- Passing primitive values
- Sending complex objects
- Using Serializable and Parcelable
- Modern Activity Result API approach
- Best practices and pitfalls
Understanding Intents
In Android, an Intent is used to navigate between Activities. An Intent can carry data using extras, which act like key/value pairs.
Passing Simple Data with Intent Extras
Sending Data
In your source Activity:
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("KEY_NAME", "JavaTechig");
intent.putExtra("KEY_AGE", 26);
startActivity(intent);
Receiving Data
In the target Activity:
Intent intent = getIntent();
String name = intent.getStringExtra("KEY_NAME");
int age = intent.getIntExtra("KEY_AGE", 0);
✔ getStringExtra() returns null if missing
✔ getIntExtra() requires a default value
Passing Multiple or Combined Data
You can bundle multiple data pieces:
Intent intent = new Intent(this, SecondActivity.class);
Bundle bundle = new Bundle();
bundle.putString("name", "John");
bundle.putInt("age", 30);
intent.putExtras(bundle);
startActivity(intent);
Retrieve Bundle:
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
String name = bundle.getString("name");
int age = bundle.getInt("age");
}
Passing Complex Objects
To send custom objects between Activities, they must be Serializable or Parcelable.
Using Serializable
Create Model
public class User implements Serializable {
private String name;
private int age;
// getters & setters omitted
}
Pass Object
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("KEY_USER", user);
startActivity(intent);
Retrieve Object
User user = (User) getIntent().getSerializableExtra("KEY_USER");
Simple to implement
Slower than Parcelable for large objects
Using Parcelable (Recommended)
Parcelable is optimized for Android and faster than Serializable.
Implement Parcelable
public class User implements Parcelable {
private String name;
private int age;
protected User(Parcel in) {
name = in.readString();
age = in.readInt();
}
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];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
}
}
Send Parcelable
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("KEY_USER", user);
startActivity(intent);
Retrieve Parcelable
User user = getIntent().getParcelableExtra("KEY_USER");
Faster than Serializable
✔ Android best practice for object passing
Passing Data and Getting Result (Two-Way Communication)
Modern Android recommends using Activity Result APIs instead of the deprecated startActivityForResult().
Register a Result Launcher
private ActivityResultLauncher<Intent> resultLauncher;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
resultLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == RESULT_OK) {
Intent data = result.getData();
String message = data.getStringExtra("RESULT_DATA");
textView.setText(message);
}
}
);
}
Launch the Activity for Result
Intent intent = new Intent(this, SecondActivity.class);
resultLauncher.launch(intent);
Return a Result
In the child Activity:
Intent intent = new Intent();
intent.putExtra("RESULT_DATA", "Some Value");
setResult(RESULT_OK, intent);
finish();
Passing Large Data Sets
For large content (images, lists), avoid passing via Intent extras due to memory limits.
✔ Use Shared ViewModel (with Jetpack Navigation)
✔ Use a persistent cache or database
✔ Store large data in disk or memory and pass a reference or ID
Best Practices (Senior Engineering Insight)
✔ Use Parcelable for performance and Android compatibility
✔ Avoid magic keys — define them in a constants class
✔ Always check for null when receiving data
✔ Prefer Activity Result API for modern result handling
✔ For long strings/images use URIs or shared cache
Example constant keys:
public class IntentConstants {
public static final String KEY_USER = "key_user";
public static final String KEY_AGE = "key_age";
}
Handling Edge Cases
✔ Data missing in Intent → handle defaults
✔ Receiving Activity recreated on rotation → preserve state via ViewModel
✔ Inter-process data sharing → use Content Providers or AIDL
Summary
Passing data between Activities in Android is fundamental. You can transfer:
- Primitive values using Intent extras
- Bundles for grouped data
- Serializable / Parcelable for complex objects
- Activity Result APIs for returning results
Using modern Android APIs ensures cleaner, maintainable code and better performance.


