解组由@Parcelize 创建的 Parcelable

Unmarshall Parcelable created by @Parcelize

我有一组 classes 实现 Parcelable 并由 @Parcelize 注释。

这些 classes 被序列化为这样的字节数组:

 return Parcel
            .obtain()
            .let { parcel ->
                writeToParcel(parcel, 0) // "this" is the Parcelable object 
                parcel
                    .marshall()
                    .also { parcel.recycle() }
            }

我想创建一个通用的反序列化方法来从字节数组创建 class 的实例:

        fun <T> create(data: ByteArray): T {
            val parcel = parse(data)

            TODO("???")
        }

        private fun parse(data: ByteArray): Parcel {
            return Parcel
                .obtain()
                .apply {
                    unmarshall(data, 0, data.size)
                    setDataPosition(0)
                }
        }

那么,如何从 Parcel 中读取通用 Parcelable

是的,我知道我可以使用Parcelable.Creator,但是我应该如何从@Parcelize生成的代码中获取它?

目前,我发现的最佳通用解决方案是使用反射实现的:

internal inline fun <reified T : Parcelable> ByteArray.deserializeParcelable(): T {
    val parcel = Parcel
        .obtain()
        .apply {
            unmarshall(this@deserializeParcelable, 0, size)
            setDataPosition(0)
        }

    return parcelableCreator<T>()
        .createFromParcel(parcel)
        .also {
            parcel.recycle()
        }
}

internal inline fun <reified T : Parcelable> parcelableCreator(): Parcelable.Creator<T> {
    val creator = T::class.java.getField("CREATOR").get(null)
    @Suppress("UNCHECKED_CAST")
    return creator as Parcelable.Creator<T>
}

我们必须使用反射,因为 @Parcelize 生成的 CREATOR 在这种方法中无法访问。