如何将 Parcel.readTypedList() 与 kotlin-android-extensions 中的 @Parcelize 一起使用?
How to use Parcel.readTypedList() along with @Parcelize from kotlin-android-extensions?
我 运行 遇到了在视图中实现基于 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()
,因为它既需要类型列表,又需要 parcelable 的 CREATOR
字段!
类 标记为:
@Parcelize
data class MyParcelable(val someData: String): Parcelable {
}
没有CREATOR,事实上,如果你尝试实现,它说:
'CREATOR' definition is not allowed. Use 'Parceler' companion object instead.
我不想要一个Parceler伴生对象,我需要一个CREATOR!
我也有点不想手动编写 Parcelable 实现,所以我可能只是让它可序列化并且像 "whatever".
有谁偶然知道如何将 Parcel.readTypedList()
与 @Parcelize
注释的 Kotlin 数据一起使用 class?
就像你提到的那样,这是 Parcelize 插件上的一个错误 https://youtrack.jetbrains.com/issue/KT-19853,它可以通过反射解决,或者实际上,你可以有一个代理 class 到 java访问 java 中的 CREATOR
字段没有任何问题。
我为所有创作者制作了一个实用程序 java class,然后制作了一个引用该创作者的 kotlin 扩展
Java
@NonNull
public static Parcelable.Creator<Blah> getBlahCreator() {
return Blah.CREATOR;
}
科特林
val Blah.Companion.CREATOR: Parcelable.Creator<Blah>
get() = UtilClass.getBlahCreator()
现在我可以在任何地方访问 Blah.CREATOR
!在可预见的未来,错误得到修复后,这两个具有所有创建者和扩展的 classes 可能会被删除,并且它会按预期工作而无需在其他 classes 中进行任何编辑使用 CREATOR
我觉得这个比反射方案好多了!但无论哪种方式,它们都很恶心,我希望这个错误能尽快修复!
因为我在 class 中遇到了同样的问题,所以对该问题投了赞成票,但由于我是新用户,所以它不可见。
我使用了下面的替代方法,(readArrayList)虽然它有细微的差别
readTypedList
arrayListOf<YourParcelableClass>().apply { parcel.readArrayList(YourParcelableClass::class.java.classLoader) }
感谢接受的解决方案,但不确定为什么,即使在 java class 文件中我也无法读取 CREATOR 字段。
https://github.com/JetBrains/kotlin/commit/fc013c6b9f5f3083d06385803ff687dc9a6ab4f0#
从 Kotlin 1.6.21 开始,
我们可以使用 parcelableCreator() from
import kotlinx.parcelize.parcelableCreator
val dataClass = TestDataClass("someValue")
val creator = parcelableCreator<TestDataClass>()
val parcel: Parcel? = null
parcel?.createTypedArrayList(creator) // Will compile
我 运行 遇到了在视图中实现基于 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()
,因为它既需要类型列表,又需要 parcelable 的 CREATOR
字段!
类 标记为:
@Parcelize
data class MyParcelable(val someData: String): Parcelable {
}
没有CREATOR,事实上,如果你尝试实现,它说:
'CREATOR' definition is not allowed. Use 'Parceler' companion object instead.
我不想要一个Parceler伴生对象,我需要一个CREATOR!
我也有点不想手动编写 Parcelable 实现,所以我可能只是让它可序列化并且像 "whatever".
有谁偶然知道如何将 Parcel.readTypedList()
与 @Parcelize
注释的 Kotlin 数据一起使用 class?
就像你提到的那样,这是 Parcelize 插件上的一个错误 https://youtrack.jetbrains.com/issue/KT-19853,它可以通过反射解决,或者实际上,你可以有一个代理 class 到 java访问 java 中的 CREATOR
字段没有任何问题。
我为所有创作者制作了一个实用程序 java class,然后制作了一个引用该创作者的 kotlin 扩展
Java
@NonNull
public static Parcelable.Creator<Blah> getBlahCreator() {
return Blah.CREATOR;
}
科特林
val Blah.Companion.CREATOR: Parcelable.Creator<Blah>
get() = UtilClass.getBlahCreator()
现在我可以在任何地方访问 Blah.CREATOR
!在可预见的未来,错误得到修复后,这两个具有所有创建者和扩展的 classes 可能会被删除,并且它会按预期工作而无需在其他 classes 中进行任何编辑使用 CREATOR
我觉得这个比反射方案好多了!但无论哪种方式,它们都很恶心,我希望这个错误能尽快修复!
因为我在 class 中遇到了同样的问题,所以对该问题投了赞成票,但由于我是新用户,所以它不可见。 我使用了下面的替代方法,(readArrayList)虽然它有细微的差别
readTypedList
arrayListOf<YourParcelableClass>().apply { parcel.readArrayList(YourParcelableClass::class.java.classLoader) }
感谢接受的解决方案,但不确定为什么,即使在 java class 文件中我也无法读取 CREATOR 字段。
https://github.com/JetBrains/kotlin/commit/fc013c6b9f5f3083d06385803ff687dc9a6ab4f0#
从 Kotlin 1.6.21 开始, 我们可以使用 parcelableCreator() from
import kotlinx.parcelize.parcelableCreator
val dataClass = TestDataClass("someValue")
val creator = parcelableCreator<TestDataClass>()
val parcel: Parcel? = null
parcel?.createTypedArrayList(creator) // Will compile