android - “Parcelable 协议需要一个名为 CREATOR 的 Parcelable.Creator 对象”(我确实有 CREATOR) - 在 Kotlin 中
问题描述
我收到错误消息“Parcelable 协议需要一个名为 CREATOR 的 Parcelable.Creator 对象在类......”,但我确实有一个 Creator,但我不知道它有什么问题。我从https://developer.android.com/reference/android/os/Parcelable复制了它并更改了类名以适合我的代码。我怀疑从 Java 到 Kotlin 的(自动)转换并不完美(或者准确地说:它是否与需要的略有不同),但我不知道问题到底是什么。
有一个带有相同错误消息的线程(Parcelable 协议需要一个名为 CREATOR 的 Parcelable.Creator 对象(我确实有 CREATOR))但问题是“有趣的 writeToParcel”没有按照读取的顺序写入“有趣的数据处理程序”。就我而言,这不是问题,因为它的顺序相同。
那里的另一个答案指出,函数需要是静态的可能是个问题。但是,Kotlin 没有“静态”功能。我读到它是用“伴侣对象”完成的。我试过了(见下文),但它引发了另一个错误 - 我不确定它是否会起作用。
class DataHandler : Parcelable {
var player1name = ""
var player1color = 0
//main constructor
fun DataHandler(player1name: String, player1color: Int) {
this.player1name = player1name
this.player1color = player1color
}
//write object values to parcel for storage
override fun writeToParcel(dest: Parcel, flags: Int) {
//write all properties to the parcle
dest.writeString(player1name)
dest.writeInt(player1color)
}
//constructor used for parcel
fun DataHandler(parcel: Parcel) {
//read and set saved values from parcel
player1name = parcel.readString()
player1color = parcel.readInt()
}
//creator - used when un-parceling our parcle (creating the object)
val CREATOR: Parcelable.Creator<DataHandler> = object : Parcelable.Creator<DataHandler> {
override fun createFromParcel(parcel: Parcel): DataHandler {
return DataHandler(parcel) as DataHandler
}
override fun newArray(size: Int): Array<DataHandler?> {
return arrayOfNulls<DataHandler>(size)
}
}
//return hashcode of object
override fun describeContents(): Int {
return hashCode()
}
}
这是发送活动:
val intentPickPlayer = Intent(this, PlayGame::class.java)
var dataHandler = DataHandler()
dataHandler.player1name = "testing"
intentPickPlayer.putExtra("data", dataHandler)
startActivity(intentPickPlayer)
这是接收活动:
class PlayGame : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.playgame)
val test = intent.getParcelableExtra<DataHandler>("data")
Toast.makeText(this, test.player1name, Toast.LENGTH_SHORT).show()
}
如上所述:我试图通过将 CREATOR 放入伴随对象中来使其成为静态(显然这是它在 Kotlin 中的工作方式,但这会产生另一个错误(我不确定它是否解决了第一个问题)
companion object {
//creator - used when un-parceling our parcle (creating the object)
val CREATOR: Parcelable.Creator<DataHandler> = object : Parcelable.Creator<DataHandler> {
override fun createFromParcel(parcel: Parcel): DataHandler {
//HERE COMES AN ERROR: parcel has a red underlining and it says: "too many Arguments for public constructor DataHandler()
return DataHandler(parcel) as DataHandler
}
override fun newArray(size: Int): Array<DataHandler?> {
return arrayOfNulls<DataHandler>(size)
}
}
解决方案
在 Kotlin 中,构造函数由constructor
关键字定义 - https://kotlinlang.org/docs/reference/classes.html
有关辅助构造函数的信息,另请参阅https://kotlinlang.org/docs/reference/classes.html#secondary-constructors。辅助构造函数需要委托给主构造函数。
默认构造函数通常在定义为它的一部分的类名和属性之后定义:
类 DataHandler(var player1name: String, var player1color: Int) : Parcelable { //将对象值写入parcel进行存储 覆盖有趣的 writeToParcel(dest: Parcel, flags: Int) { //将所有属性写入parcle dest.writeString(player1name) dest.writeInt(player1color) } //用于包裹的构造函数 构造函数(包裹:包裹):这个( //从包裹中读取并设置保存的值 player1name = parcel.readString(), player1color = parcel.readInt()) 伴随对象{ @JvmField //creator - 在解包我们的包裹时使用(创建对象) val 创建者:Parcelable.Creator = 对象:Parcelable.Creator { 覆盖乐趣 createFromParcel(parcel: Parcel): DataHandler { 返回 DataHandler(parcel) 作为 DataHandler } 覆盖有趣的 newArray(size: Int): Array { 返回arrayOfNulls(大小) } } } //返回对象的hashcode 覆盖有趣的 describeContents(): Int { 返回哈希码() } }
推荐阅读
- macos - docker 在 macOS 上需要巨大的磁盘空间
- bash - Bash robocopy 从包含文件夹路径的文本文件和要使用特殊字符复制的文件
- python - discord py - 机器人忽略“如果”检查
- python - TypeError:“NoneType”对象在将 JSON 分配给 python 变量的 GAE 实例上不可下标
- java - 在 PicoContainer 的多个接口下注册同一个类
- excel - 使用 forge-api npm 的 getObject(),如何将返回结果作为下载链接?
- sql - Scala、Quill、Postgres - 由于“ON CONFLICT”错误而无法插入数据库
- python - 处理熊猫数据框中的列
- sql - 需要一个 SQL Server 查询来消除突出显示的行(返回飞行中的路线)
- python - 熊猫数据透视表方法返回错误