Kotlin Android extensions 入面有一個實驗功能:Parcelize。它是一個 annotation,只需要在 data class 加上 @Parcelize annotation 和 implement Parcelable interface 就能夠在 compile 時自動生成所需的 boilerplate。

@Parcelize
data class Product(val name: String, val price: Double) : Parcelable

留意要在 build.gradle 加上:

androidExtensions {
    experimental = true
}

這個基本用法在不少網站都有介紹過,的確可以節省不少時間 copy and paste code,或者可以不需要再用 PaperParcel 之類的 library。不過如果要自訂個別 property 的 adapter 的話(例如那個 property 的 data type 不是自己的 class 又沒有 implement Parcelable),就可以用 @WriteWith 來註明 adapter:

@Parcelize
data class Product(
    val name: String,
    val price: Double,
    val expiryDate: @WriteWith<ExpiryDateParceler> ExpiryDate
) : Parcelable

假設我們有個 ExpiryDate 的 field,在 type 前面加入 @WriteWith annotation。ExpiryDateParceler 就是我們特別為 ExpiryDate 寫的 adapter object class。

object ExpiryDateParceler : Parceler<ExpiryDate> {
    override fun create(parcel: Parcel): ExpiryDate = ExpiryDate.createByFullDate(parcel.readString())

    override fun ExpiryDate.write(parcel: Parcel, flags: Int) {
        parcel.writeString(this.fullDate)
    }
}

Parceler 有兩個 method 要實作:一個是從 ExpiryDate serialize 變成 Parcel;另一個是由 Parcel deserialize 變成 ExpiryDate。這個例子用了 string 來 serialize,你可以用其他 type 來 serialize,最重要是之後可以被還原。留意必須使用 object class。

如果 ExpiryDate 是 nullable 的話,在 ExpiryDateParcelerExpiryDate 改成 ExpiryDate? 即可。