解组由@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
在这种方法中无法访问。
我有一组 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
在这种方法中无法访问。