A Guide to Parcelable and Serializable in Android with Kotlin

A Guide to Parcelable and Serializable in Android with Kotlin

Introduction

In Android app development, the need to pass data between different components of an app is common. Two common approaches for achieving this are through the use of Parcelable and Serializable. In this blog, we'll explore the differences between Parcelable and Serializable, their use cases, and provide code snippets in Kotlin to demonstrate how to implement each method.

Use Cases:

  • Parcelable:

    • When you need to pass data between activities or fragments within an Android app.

    • When performance and memory efficiency are important due to frequent data passing.

    • For cases where you're dealing with complex data structures or large objects.

  • Serializable:

    • When passing data between components in a Java application or when dealing with non-Android contexts.

    • When simplicity is preferred over performance optimization.

    • For one-time serialization tasks that don't involve frequent data passing.

Implementation:

Parcelable:

  1. Create a Kotlin data class for the object you want to make Parcelable:

     import android.os.Parcel
     import android.os.Parcelable
    
     data class Person(val name: String?, val age: Int) : Parcelable {
         constructor(parcel: Parcel) : this(
             parcel.readString(),
             parcel.readInt()
         )
    
         override fun writeToParcel(parcel: Parcel, flags: Int) {
                 parcel.writeString(name)
             parcel.writeInt(age)
         }
    
         override fun describeContents(): Int {
             return 0
         }
    
         companion object CREATOR : Parcelable.Creator<Person> {
             override fun createFromParcel(parcel: Parcel): Person {
                 return Person(parcel)
             }
    
             override fun newArray(size: Int): Array<Person?> {
                 return arrayOfNulls(size)
             }
         }
     }
    
  2. Sending data from one activity to another:

     val person = Person("Alice", 30)
     val intent = Intent(this, SecondActivity::class.java)
     intent.putExtra("person", person)
     startActivity(intent)
    
  3. Receiving data in the second activity:

      val parcelableData: Person? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
          intent.getParcelableExtra("person", Person::class.java)
      } else {
          intent.getParcelableExtra("person") as? Person
      }
    

Serializable:

  1. Create a Kotlin class for the object you want to make Serializable:

     import java.io.Serializable
    
     data class Person(val name: String?, val age: Int) : Serializable
    
  2. Sending data from one activity to another:

     val person = Person("Alice", 30)
     val intent = Intent(this, SecondActivity::class.java)
     intent.putExtra("person", person)
     startActivity(intent)
    
  3. Receiving data in the second activity:

     val data: Person? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
         intent.getSerializableExtra("person", Person::class.java)
     } else {
         intent.getSerializableExtra("person") as? Person
     }
    

Why parcelable is faster than serializable?

  1. Selective Serialization: Parcelable allows you to selectively serialize only the necessary fields of an object. This can be more efficient than Serializable, which serializes the entire object by default. By choosing which fields to serialize, you can optimize the process.

  2. Android-Specific Optimization: Parcelable was specifically designed for Android, and the Android platform provides optimized code for Parcelable objects during the serialization and deserialization process. This can result in faster performance compared to the more general-purpose Serializable interface.

  3. Internal Implementation: Parcelable uses a custom serialization mechanism that is optimized for Android's internals. It generates a highly optimized bytecode during compilation, tailored for the Android environment. In contrast, Serializable relies on Java's default serialization mechanism, which might be less efficient for Android use cases.

  4. Less Reflection Overhead: Parcelable typically involves less reflection overhead than Serializable. Reflection is a process that allows a program to inspect or modify its own structure, properties, and behavior. Parcelable often requires less reflection during the serialization and deserialization process.

  5. Reduced Garbage Collection: Parcelable often generates less temporary objects during the serialization and deserialization process, leading to reduced garbage collection overhead. This can be beneficial for performance, especially in resource-constrained environments like mobile devices.

Conclusion:

Both Parcelable and Serializable offer ways to pass data between components in Android and Java applications. Parcelable is preferred within Android development due to its optimized performance, especially when dealing with complex objects. On the other hand, Serializable provides a simpler approach but might not be as efficient for high-frequency data passing. Choose the approach that best fits your use case and performance requirements.

Happy coding :)