在View中实现基于Parcelable的状态持久化时遇到了问题。即,因为我需要像这样实现BaseSavedState
的方法:
class SavedState : BaseSavedState {
lateinit var myList: ArrayList<MyParcelable>
constructor(superState: Parcelable) : super(superState) {}
private constructor(parcel: Parcel) : super(parcel) {
val listSize = parcel.readInt()
val list = ArrayList<MyParcelable>(listSize)
this.myList = parcel.readTypedList(list, /* needs MyParcelable.CREATOR */ )
}
override fun writeToParcel(out: Parcel, flags: Int) {
super.writeToParcel(out, flags)
out.writeInt(myList.size())
out.writeTypedList(myList)
}
companion object {
@JvmField
val CREATOR: Parcelable.Creator<SavedState> = object : Parcelable.Creator<SavedState> {
override fun createFromParcel(`in`: Parcel): SavedState {
return SavedState(`in`)
}
override fun newArray(size: Int): Array<SavedState?> {
return arrayOfNulls(size)
}
}
}
}
但是,正如您所看到的,我似乎无法使用Parcel.readTypedList()
,因为它既需要类型列表,又需要可包裹的CREATOR
字段!
类标记为:
@Parcelize
data class MyParcelable(val someData: String): Parcelable {
}
没有创建者,实际上,如果您尝试实现,它会说:
不允许使用“ CREATOR”定义。请改用“包裹”辅助对象。
我不想要一个包裹伴侣对象,我需要一个创造者!
我也不想手工编写Parcelable实现,因此我可能只是将其设置为Serializable,就像“随便什么”。
有人偶然知道如何将Parcel.readTypedList()
与带有注释的@Parcelize
的Kotlin数据类一起使用吗?
答案 0 :(得分:3)
就像您提到的https://youtrack.jetbrains.com/issue/KT-19853一样,这是Parcelize插件上的错误,可以通过反射或实际上解决,您可以拥有Java的代理类,因为您可以访问Java中的CREATOR
字段没有任何问题。
我为所有创建者创建了一个util java 类,然后进行了指向该创建者的kotlin扩展
Java
@NonNull
public static Parcelable.Creator<Blah> getBlahCreator() {
return Blah.CREATOR;
}
科特琳
val Blah.Companion.CREATOR: Parcelable.Creator<Blah>
get() = UtilClass.getBlahCreator()
现在我可以在任何地方访问Blah.CREATOR
了!而且,在可预见的将来修复了该错误之后,可以将这两个具有所有创建者和扩展名的类删除,并且可以按预期工作,而无需对其他使用CREATOR
的类进行任何编辑>
对我来说,这比反射解决方案好得多!但是无论哪种方式,它们都令人恶心,我希望这个错误能够尽快得到解决!
答案 1 :(得分:1)
针对该问题进行了投票,因为我在一个班级中遇到了相同的问题,但由于我是新用户而无法看到。 我使用了以下替代方法,(readArrayList)尽管有细微差别
readTypedList
arrayListOf<YourParcelableClass>().apply { parcel.readArrayList(YourParcelableClass::class.java.classLoader) }
感谢接受的解决方案,但不确定为什么,即使在Java类文件中,我也无法读取CREATOR字段。