【问题标题】:Unmarshall Parcelable created by @Parcelize由@Parcelize 创建的 Unmarshall Parcelable
【发布时间】:2020-12-04 18:10:32
【问题描述】:

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

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

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

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

        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生成的代码中获取呢?

【问题讨论】:

  • 我的猜测是您将需要使用反射,并带有一个具体化的T,这样您就知道如何构建您正在寻找的特定类。

标签: android kotlin annotations parcelable


【解决方案1】:

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

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在这些方法中是无法访问的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-06
    • 1970-01-01
    • 1970-01-01
    • 2020-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多