Search code examples
androidkotlinparcelable

Kotlin parcelable and arrayList of parcelables


I am trying to write a parcelable data object to pass to from activityA to activityB in my android application.

My object is passing with all the data, except my arraylist of the class Available Service

data class AvailableService(val id: Int,
                        val name: String,
                        val description: String,
                        val price: Double,
                        val currency: String,
                        val imageUrl: String) : Parcelable {

companion object {
    @JvmField @Suppress("unused")
    val CREATOR = createParcel { AvailableService(it) }
}

protected constructor(parcelIn: Parcel) : this(parcelIn.readInt(),
        parcelIn.readString(),
        parcelIn.readString(),
        parcelIn.readDouble(),
        parcelIn.readString(),
        parcelIn.readString())

override fun writeToParcel(dest: Parcel?, flags: Int) {
    dest?.writeInt(id)
    dest?.writeString(name)
    dest?.writeString(description)
    dest?.writeDouble(price)
    dest?.writeString(currency)
    dest?.writeString(imageUrl)
}

override fun describeContents() = 0
}

above is the available serviceClass, next I have Trip, which holds an arraylist of AvailableService.. I observed this in debug, it is successfully writing the arraylist, for some reason I have an issue with reading the data.

data class Trip(val id: String,
            val status: String,
            val orderedServices: ArrayList<OrderedService>) : Parcelable {

companion object {
    @JvmField @Suppress("unused")
    val CREATOR = createParcel { Trip(it) }
}

protected constructor(parcelIn: Parcel) : this(parcelIn.readString(),
        parcelIn.readString(),
        arrayListOf<OrderedService>().apply {
            parcelIn.readArrayList(OrderedService::class.java.classLoader)
        }
)

override fun writeToParcel(dest: Parcel?, flags: Int) {
    dest?.writeString(id)
    dest?.writeString(status)
    dest?.writeList(orderedServices)
}

override fun describeContents() = 0
}

in case someone wonders what's the fun of the CREATOR does, code below:

inline fun <reified T : Parcelable> createParcel(
    crossinline createFromParcel: (Parcel) -> T?): Parcelable.Creator<T> =
    object : Parcelable.Creator<T> {
        override fun createFromParcel(source: Parcel): T? = createFromParcel(source)
        override fun newArray(size: Int): Array<out T?> = arrayOfNulls(size)
    }

again, writing succeeds, but reading fails, I get an empty arraylist.. I think that part is the faulty one:

arrayListOf<OrderedService>().apply {
        parcelIn.readArrayList(OrderedService::class.java.classLoader)
    }

is there a different way to read/write arraylist? am I writing it wrong? reading it wrong?

thanks in advance for any help!


Solution

  • Replace:

    arrayListOf<OrderedService>().apply {
        parcelIn.readArrayList(OrderedService::class.java.classLoader)
    }
    

    with:

    arrayListOf<OrderedService>().apply {
        parcelIn.readList(this, OrderedService::class.java.classLoader)
    }