ArrayList<ArrayList<String>> in Parcelable object kotlin

隐身守侯 提交于 2019-12-22 22:06:07

问题


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) {
    // ?????
  }

}

回答1:


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.



来源:https://stackoverflow.com/questions/55056972/arraylistarrayliststring-in-parcelable-object-kotlin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!