Kotlin中的Parcelable和Parcelable数组

26

我正在尝试编写一个可传递的数据对象,以便在我的Android应用程序中从ActivityA传递到ActivityB

我的对象传递了所有数据,但是我的Available Service类的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
}

以上是可用的serviceClass,接下来是Trip,它持有一个AvailableServicearraylist。我在调试中观察到这一点,它成功地写入了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
}

如果有人想知道创建者的乐趣在哪里,可以看下面的代码:

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)
    }

再次出现写入成功但读取失败的问题,我得到了一个空的ArrayList。 我认为问题在于以下这部分:

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

有没有不同的方法来读/写 ArrayList?我是不是写错了?读错了吗?

提前感谢您的帮助!

4个回答

42

替换:

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

随着:

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

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

to

source.createTypedArrayList(OrderedService.CREATOR)

将“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)
    }
}

不好意思,您的解决方案出现了崩溃(错误:在偏移量13200处无法解组未知类型代码55),第一个响应是可以的。 - Benoit Canonne

6
对于API 29及以上版本:
替换为:
arrayListOf<OrderedService>().apply {
    parcelIn.readArrayList(OrderedService::class.java.classLoader)
}

使用

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

并且

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

使用

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>)
    }
}

3
如果父模型和子模型都有可序列化,则请使用以下方法:
父模型如下:
Parcelable {
    constructor(parcel: Parcel) : this(
        parcel.createTypedArrayList(ImagesModel.CREATOR)
    )
}

override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeTypedList(images)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接