“Parcelable 协议需要一个名为 CREATOR 的 Parcelable.Creator 对象”(我确实有 CREATOR)- 在 Kotlin 中
Posted
技术标签:
【中文标题】“Parcelable 协议需要一个名为 CREATOR 的 Parcelable.Creator 对象”(我确实有 CREATOR)- 在 Kotlin 中【英文标题】:"Parcelable protocol requires a Parcelable.Creator object called CREATOR" (I do have CREATOR) - in Kotlin 【发布时间】:2019-01-17 00:21:17 【问题描述】:我收到错误消息“Parcelable 协议需要一个 Parcelable.Creator 对象,名为 CREATOR 在类.....”,但我确实有一个 Creator,但我不知道它有什么问题。我从https://developer.android.com/reference/android/os/Parcelable 复制了它并更改了类名以适合我的代码。 我怀疑从 Java 到 Kotlin 的(自动)转换并不完美(或者准确地说:它是否与需要的略有不同),但我不知道问题到底出在哪里。
有一个线程具有相同的错误消息 (Parcelable protocol requires a Parcelable.Creator object called CREATOR (I do have CREATOR)) 但问题是 “fun writeToParcel”的写入顺序与“fun DataHandler”中读取的顺序不同。就我而言,这不是问题,因为它的顺序相同。
那里的另一个答案指出,函数需要是静态的可能是个问题。但是,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)
【问题讨论】:
你能试试companion object CREATOR : ...
吗?
既不是:伴生对象 CREATOR : Parcelable.Creator@JvmField
标记CREATOR
。
【参考方案1】:
在 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 返回哈希码()【讨论】:
? @RaphaelFritz 您能否将此标记为已接受的答案? ***.com/help/someone-answers以上是关于“Parcelable 协议需要一个名为 CREATOR 的 Parcelable.Creator 对象”(我确实有 CREATOR)- 在 Kotlin 中的主要内容,如果未能解决你的问题,请参考以下文章