Kotlin parcelable和arrayList of parcelables

Joz*_*eRi 17 android parcelable kotlin

我试图写一个parcelable数据对象从传递到activityAactivityB在我的Android应用程序.

我的对象是传递所有数据,除了我arraylist的可用服务类

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
}
Run Code Online (Sandbox Code Playgroud)

上面是可用的serviceClass,接下来我有旅行,其持有arraylistAvailableService..我在调试观察这一点,它成功地写arraylist,由于某种原因,我有一个问题与读取数据.

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
}
Run Code Online (Sandbox Code Playgroud)

万一有人想知道CREATOR的乐趣是什么,代码如下:

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)
    }
Run Code Online (Sandbox Code Playgroud)

再次,写作成功,但阅读失败,我得到一个空arraylist...我认为那部分是错误的:

arrayListOf<OrderedService>().apply {
        parcelIn.readArrayList(OrderedService::class.java.classLoader)
    }
Run Code Online (Sandbox Code Playgroud)

是否有不同的读/写方式arraylist?我写错了吗?读错了吗?

在此先感谢您的帮助!

小智 33

更换:

arrayListOf<OrderedService>().apply {
    parcelIn.readArrayList(OrderedService::class.java.classLoader)
}
Run Code Online (Sandbox Code Playgroud)

有:

arrayListOf<OrderedService>().apply {
    parcelIn.readList(this, OrderedService::class.java.classLoader)
}
Run Code Online (Sandbox Code Playgroud)


Ron*_*ini 6

更改

arrayListOf<OrderedService>().apply {
    parcelIn.readArrayList(OrderedService::class.java.classLoader)
}
Run Code Online (Sandbox Code Playgroud)

source.createTypedArrayList(OrderedService.CREATOR)
Run Code Online (Sandbox Code Playgroud)

更改 dest?.writeList(orderedServices)

dest?.writeTypedList(orderedServices)

创作者方法

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


Joh*_*eos 6

适用于 API 29 及以上

代替:

arrayListOf<OrderedService>().apply {
    parcelIn.readArrayList(OrderedService::class.java.classLoader)
}
Run Code Online (Sandbox Code Playgroud)

if (Build.VERSION.SDK_INT >= 29)
    parcel.readParcelableList(this, OrderedService::class.java.classLoader)
else
    parcel.readList(this as List<OrderedService>, OrderedService::class.java.classLoader)
}
Run Code Online (Sandbox Code Playgroud)

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

override fun writeToParcel(dest: Parcel?, flags: Int) {
    dest?.writeString(id)
    dest?.writeString(status)
    if (Build.VERSION.SDK_INT >= 29) {
        dest?.writeParcelableList(orderedServices,flags)
    } else {
        dest?.writeList(orderedServices as List<OrderedService>)
    }
}
Run Code Online (Sandbox Code Playgroud)