Aung Thiha
Aung Thiha

Reputation: 1215

ArrayList<ArrayList<String>> in Parcelable object kotlin

Array of arrays of strings needs to be parcelized. The object is like so

data class Foo (
    @SerializedName("bar") val bar: ArrayList<ArrayList<String>>,
)

It doesn't exactly need to be ArrayList. Array can also used.

data class Foo (
    @SerializedName("bar") val bar: Array<Array<String>>,
)

Whichever easier is ok to map this json data

{
  "bar": [
    ["a", "b"],
    ["a1", "b2", "c2"],
    ["a3", "b34", "c432"]
  ]
}

Using kotlin experimental Parcelize crashes the app when it's compiled with progaurd

How is it written in "writeToParcel" and read in "constructor"?

data class Foo (
  @SerializedName("bar") val bar: ArrayList<ArrayList<String>>,
) : Parcelable {

  constructor(source: Parcel) : this(
     // ?????
  )

  override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
    // ?????
  }

}

Upvotes: 2

Views: 3501

Answers (1)

Jeel Vankhede
Jeel Vankhede

Reputation: 12118

You can't directly create Parcelable for List of List directly, so one solution is to make one subclass of your desired List as Parcelable and take it as you final list type. How? check out below :

Let's first create our internal List of String class like below :

class StringList() : ArrayList<String>(), Parcelable {
    constructor(source: Parcel) : this() {
        source.createStringArrayList()
    }

    override fun describeContents() = 0

    override fun writeToParcel(dest: Parcel, flags: Int) {
        dest.writeStringList(this@StringList)
    }

    companion object {
        @JvmField
        val CREATOR: Parcelable.Creator<StringList> = object : Parcelable.Creator<StringList> {
            override fun createFromParcel(source: Parcel): StringList = StringList(source)
            override fun newArray(size: Int): Array<StringList?> = arrayOfNulls(size)
        }
    }
}

What we've done here is created our ArrayList<String> parcelable so that we can use it at any endpoint.

So final data class would be having following implementation :

data class Foo(@SerializedName("bar") val bar: List<StringList>) : Parcelable {
    constructor(source: Parcel) : this(
        source.createTypedArrayList(StringList.CREATOR)
    )

    override fun describeContents() = 0

    override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
        writeTypedList(bar)
    }

    companion object {
       @JvmField
       val CREATOR: Parcelable.Creator<Foo> = object : Parcelable.Creator<Foo> {
            override fun createFromParcel(source: Parcel): Foo = Foo(source)
            override fun newArray(size: Int): Array<Foo?> = arrayOfNulls(size)
       }
    }
}

Note: It's simple implementation based on O.P., you can make any customization based on your requirement.

Upvotes: 3

Related Questions