Deep clones with Android Parcelable

Photo by Jørgen Håland on Unsplash

Deep Clones

There are many ways to create deep clones of an object, from Java’s Clone() function to Copy Constructors to custom implementations. All methods come with their own problems and a lot of boilerplate code.

With Parcelable and advent of Kotlin, creating simple deep clones can be of no effort in your android project.

Why Parcelable?

Serialization is a technique to convert objects into a byte stream and Deserialization vice versa. In this process totally new objects are created (i.e. Object’s clone).

Serialization will create deep clones of the entire object graph, unlike shallow clones, where only the parent object is cloned and references of children objects are copied to the new object. Kotlin’s copy() function creates shallow clones.

There are 2 ways to serialize objects in android

  1. Parcelable
  2. Serializable

Parcelable is android’s replacement to Java’s Serializable. Unlike Serializable, Parcelable does not rely on reflection which makes it much faster and memory efficient.

Though smartphones today have come a long way, performance tuning and memory management are never not a problem. Choosing Parcelable over Serializable can be of help.

How does it work?

Let’s say we have a Person object that we need to clone.

@Parcelize
data class Person(val name:String,val email:String):Parcelable

Following method is the secret sauce of this article. It leverages Parcelable to do the cloning. I’ve made it generic to work with all type of objects.

fun <T : Parcelable> deepClone(objectToClone: T): T? {
        var parcel: Parcel? = null
        return try {
            parcel = Parcel.obtain()
            parcel.writeParcelable(objectToClone, 0)
            parcel.setDataPosition(0)
            parcel.readParcelable(objectToClone::class.java.classLoader)
        } finally {
            //it is important to recyle parcel and free up resources once done.
            parcel?.recycle()
        }
    }

Now to create clone and print results.

..

val bob = Person(name="Bob",email="bob@builder.com")
val bobClone = deepClone(bob)
Log.d("Clone Parcelable ->", "bob's content $bob")
Log.d("Clone Parcelable ->", "clone content $bobClone")
Log.d("Clone Parcelable ->", "are references equal ${bob === bobClone} ")
Log.d("Clone Parcelable ->", "is content equal ${bob == bobClone} ")

..
Printed Logs

A similar result can be achieved using the Serializable interface.

Pros

  • Less boilerplate code
  • Easy to implement
  • Faster than serializable

Cons

  • Parcelable interface must be implemented throughout the graph of the object to be cloned.

Conclusion

When creating clones its rarely one size fits all. It is subjective to the programmer and the requirements of the project.

Knowing this technique adds one more tool to your arsenal.

4 comments On Deep clones with Android Parcelable

Leave a reply:

Your email address will not be published.

Site Footer

Sliding Sidebar