使用@Parcelize注解时继承场景下无法获取子类类型问题
解决Parcelable子类在容器类中传递时类型丢失的问题
问题的核心是默认的@Parcelize不会自动保存父类引用的具体子类类型,导致反序列化后只能拿到父类类型。以下是几种可行的解决方案:
方案一:手动在容器类中处理类型标识
给父类添加类型标识,然后让容器类实现Parcelable时手动记录和还原子类类型:
- 给Parent类添加类型标识属性:
@Parcelize open class Parent(val type: String) : Parcelable { constructor() : this("Parent") } data class Child1() : Parent("Child1") data class Child2() : Parent("Child2")
- 实现Container类的Parcelable逻辑:
class Container(var obj: Parent) : Parcelable { constructor(parcel: Parcel) : this( when(parcel.readString()) { "Child1" -> parcel.readParcelable(Child1::class.java.classLoader)!! "Child2" -> parcel.readParcelable(Child2::class.java.classLoader)!! else -> parcel.readParcelable(Parent::class.java.classLoader)!! } ) override fun writeToParcel(parcel: Parcel, flags: Int) { parcel.writeString(obj.type) parcel.writeParcelable(obj, flags) } override fun describeContents(): Int = 0 companion object CREATOR : Parcelable.Creator<Container> { override fun createFromParcel(parcel: Parcel): Container = Container(parcel) override fun newArray(size: Int): Array<Container?> = arrayOfNulls(size) } }
序列化时先写入类型标识,反序列化时根据标识读取对应子类实例,即可还原原本的子类类型。
方案二:使用泛型容器类
如果能提前确定传递的子类类型,可用泛型约束容器类,结合@Parcelize简化实现:
@Parcelize class Container<T : Parent>(var obj: T) : Parcelable
传递与接收代码:
// 第一个Activity传递 val container = Container(Child1()) intent.putExtra("container", container) // 第二个Activity接收 val container = intent.getParcelableExtra<Container<Child1>>("container") val child1 = container?.obj // 类型为Child1
局限性:仅适用于提前知道子类类型的场景,动态不确定类型时不适用。
方案三:将Parent改为密封类
如果Parent的子类是固定有限的,改为密封类后@Parcelize会自动处理子类类型信息:
@Parcelize sealed class Parent : Parcelable @Parcelize data class Child1() : Parent() @Parcelize data class Child2() : Parent()
容器类直接用@Parcelize实现:
@Parcelize class Container(var obj: Parent) : Parcelable
密封类的Parcelable实现会自动保留子类类型,反序列化时能正确还原具体子类,是最简洁的方案,但要求子类固定。
内容的提问来源于stack exchange,提问作者Cembora
相关产品推荐
相关产品推荐

