How can I make my custom objects Parcelable?
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
Android uses the Parcelable interface to serialize objects for inter-process communication and to pass data between Activities, Fragments, and Services through Bundle and Intent extras. Unlike Java's Serializable, Parcelable avoids reflection and is significantly faster on Android. This article covers the Kotlin @Parcelize annotation, manual Java implementation, handling nested objects, and best practices for safe parceling.
Kotlin with @Parcelize
The kotlin-parcelize Gradle plugin generates the Parcelable boilerplate at compile time. You annotate a data class with @Parcelize and implement the Parcelable interface.
First, enable the plugin in your module-level build file.
Then define your data class.
The compiler generates writeToParcel() and CREATOR automatically. Every property in the primary constructor is parceled in declaration order.
Passing Parcelable Objects Between Activities
Once your class implements Parcelable, you can put it into an Intent or Bundle.
On API 33 and above, the type-safe getParcelableExtra(key, clazz) overload is preferred because it avoids unchecked cast warnings and is more explicit about the expected type.
Handling Nested Parcelable Objects
When a class contains another custom object, that nested object must also implement Parcelable.
The @Parcelize plugin handles List, Map, Set, and other standard collections automatically, as long as the element types are themselves parcelable or primitive types.
Manual Java Implementation
In Java, you implement Parcelable by writing writeToParcel() to serialize fields and a CREATOR factory to deserialize them. The field order must match exactly between the two methods.
The writeByte/readByte pattern is the standard way to parcel booleans because Parcel does not have writeBoolean/readBoolean methods on older API levels. On API 29+, writeBoolean and readBoolean are available.
Parceling Enum Types
Enums are not directly parcelable, but you can parcel them by name or ordinal.
With @Parcelize, enums are handled automatically. In manual Java parceling, write the enum's name() as a string and read it back with valueOf().
Parcelable vs Serializable
Both interfaces move objects across process boundaries, but they differ in performance and complexity.
Serializable uses reflection to discover fields at runtime, which creates temporary objects and triggers garbage collection. Parcelable writes directly to a byte buffer with no reflection. Benchmarks consistently show Parcelable is 5-10x faster for typical Android use cases. Prefer Parcelable for any object passed through Intent, Bundle, or Binder transactions.
Common Pitfalls
- Field order mismatch in manual parceling: The read order in the
Parcelconstructor must exactly match the write order inwriteToParcel(). A mismatch produces corrupted data or crashes with no clear error message. - Forgetting to parcel nested objects: If a field is a custom type that does not implement
Parcelable, the compiler (with@Parcelize) or runtime (with manual Java) will fail. Every custom type in the object graph must be parcelable. - Using Serializable for IPC-heavy paths:
Serializableworks but is significantly slower due to reflection overhead. Reserve it for non-performance-critical cases like disk persistence. - Not handling null fields in manual Java: If a
Stringfield can be null, you must write a null indicator byte before the string and check it during reads, or the deserialized value will be incorrect. - Exceeding the Binder transaction limit: The maximum
Bindertransaction size is roughly 1 MB. Parceling large objects (bitmaps, long lists) across Activities can trigger aTransactionTooLargeException. Pass identifiers instead and load data from a shared repository.
Summary
- Use Kotlin's
@Parcelizeannotation with thekotlin-parcelizeplugin to eliminate boilerplate for data classes. - In Java, manually implement
writeToParcel()andCREATOR, ensuring read and write field order matches exactly. - Nested objects and enums must also implement
Parcelableor be handled through string/ordinal conversion. - Prefer
ParcelableoverSerializablefor Android IPC because it avoids reflection and runs 5-10x faster. - Keep parceled data small to stay within the 1 MB Binder transaction limit; pass identifiers for large datasets.
- On API 33+, use the type-safe
getParcelableExtra(key, clazz)overload instead of the deprecated generic version.
Related reading
- How can I make the memberwise initialiser public, by default, for structs in Swift?
- How can I mask a UIImageView?
- How can I open a URL in Android's web browser from my application?
- How can I open a URL in Android's web browser from my application?
- How can I parse / create a date time stamp formatted with fractional seconds UTC timezone ISO 8601, RFC 3339 in Swift?
- How can I parse a local JSON file from assets folder into a ListView?
- How can I parse a local JSON file from assets folder into a ListView?
- How can I pass a Bitmap object from one activity to another
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.