Easy Parcelable in Kotlin
Parcelable
If you are an Andorid developer and ever tried to pass your custom Model or Data class from one Activity to another Activity, you must encountered with Parcelables.
Basically Parcelable is a component of Android SDK, an Interface which is similar to JAVA Serializable. It is Android’s recommended way of passing your custom data structure between different components in your app, because Parcelable is processed relatively fast compared to the standard JAVA serialization as you need to be explicit about the serialization process instead of using reflection to infer it.
To know more about Parcelable and Serializable you may visit: android-difference-between-parcelable-and-serializable
How to make my class Parcelable
Making your class Parcelable is always painful, no matter Kotlin or JAVA whatever language you use. So developer’s started to make different Android Studio plugins and libraries to make your life easier.
There are 3 ways you can make your class Parcelable:
- Implementing the Parcelable interface and defining the serialization yourself (The traditional way)
- Using Android Studio plugins, like Android Parcelable code generator
- Using annotation-based libraries, like Parceler
The example
I will be using Kotlin for our examples. Let’s say we are making an online marketplace app and we have a custom Data class called Item like following:
data class Item(
val title: String,
val details: String,
val price: Double,
val category: String
)
Parcelable: The traditional way
class Item(
val title: String,
val details: String,
val price: Double,
val category: String) : Parcelable {
companion object {
@JvmField
val CREATOR = object : Parcelable.Creator<Item> {
override fun createFromParcel(parcel: Parcel) = Item(parcel)
override fun newArray(size: Int) = arrayOfNulls<Item>(size)
}
}
private constructor(parcel: Parcel) : this(
title = parcel.readString(),
details = parcel.readString(),
price = parcel.readDouble(),
category = parcel.readString()
)
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(title)
parcel.writeString(details)
parcel.writeDouble(price)
parcel.writeString(category)
}
override fun describeContents() = 0
}
Parcelable: The lazy coder’s way
@Parcelize
data class Item(
var imageId: Int,
var title: String,
var price: Double,
var category: String
) : Parcelable
See, easy as that! You just to confirm followings:
- Use @Parcelize annotation on top of your Model / Data class
- Use latest version of Kotlin (v1.1.51 at the time of writing this article)
- Use latest version of Kotlin Android Extensions in your app module, so your build.gradle may look like:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
... ... ...
// Add for using latest experimental build of Android Extensions
androidExtensions {
experimental = true
}
}
dependencies {
... ... ...
}
Passing Complex Object as Parcelable
Let’s assume your Item is a complex object, which has another data structure Category consisting categoryId and categoryName as below:
data class Category(
var categoryId: Int,
var categoryName: String
)
You can simply use it within your Item Parcelable by making itself a Parcelable class like below:
@Parcelize
data class Category(
var categoryId: Int,
var categoryName: String
) : Parcelable
So, your final Item class may look like this:
@Parcelize
data class Item(
var imageId: Int,
var title: String,
var price: Double,
var category: Category
) : Parcelable
All you need to do is, define your nested class as another Parcelable class — that’s it!
Well, passing and retrieving the Parcelable object is even easier:
Passing the Parcelable
val intent = Intent(this, AnotherActivity::class.java)
intent.putExtra("extra_item", item)
Retrieving the Parcelable
val item = intent.getParcelableExtra("extra_item")
// Do something with the item (example: set Item title and price)
That’s all for now. Stay Lazy and Productive.
Happy coding!!