如何在Kotlin中使用Gson注册一个InstanceCreator?

我可以使用代码1将MutableList保存到json字符串使用Gson正确,但是当我尝试从代码2从json字符串恢复MutableList对象时,我得到错误。我有搜索一些资源,似乎我需要注册一个InstanceCreator。

我怎样才能用Kotlin写一个InstanceCreator代码? 谢谢!

错误

 Caused by: java.lang.RuntimeException: Unable to invoke no-args constructor for interface model.DeviceDef. Registering an InstanceCreator with Gson for this type may fix this problem. 

代码1

 private var listofMDetail: MutableList?=null mJson = Gson().toJson(listofMDetail) //Save 

代码2

 var mJson: String by PreferenceTool(this, getString(R.string.SavedJsonName) , "") var aMListDetail= Gson().fromJson<MutableList>(mJson) inline fun  Gson.fromJson(json: String) = this.fromJson(json, object: TypeToken() {}.type) 

我的课

 interface DeviceDef data class BluetoothDef(val status:Boolean=false): DeviceDef data class WiFiDef(val name:String, val status:Boolean=false) : DeviceDef data class MDetail(val _id: Long, val deviceList: MutableList) { inline fun  getDevice(): T { return deviceList.filterIsInstance(T::class.java).first() } } 

添加

当我使用val myGson = GsonBuilder().setPrettyPrinting().registerTypeAdapterFactory(adapter).create() ,我可以得到正确的结果,当我使用open class DeviceDef ,为什么?

 open class DeviceDef data class BluetoothDef(val status:Boolean=false): DeviceDef() data class WiFiDef(val name:String, val status:Boolean=false) : DeviceDef() val adapter = RuntimeTypeAdapterFactory .of(DeviceDef::class.java) .registerSubtype(BluetoothDef::class.java) .registerSubtype(WiFiDef::class.java) data class MDetail(val _id: Long, val deviceList: MutableList) { inline fun  getDevice(): T { return deviceList.filterIsInstance(T::class.java).first() } } val myGson = GsonBuilder().setPrettyPrinting().registerTypeAdapterFactory(adapter).create() 

Gson很难像在你的MutableList那样对多态对象进行反序列化。 这是你需要做的:

  1. 手动添加RuntimeTypeAdapterFactory.java到你的项目(似乎不是gson库的一部分 )。 另请参阅此答案 。

  2. 改变你的代码来使用工厂

创建Gson实例:

 val adapter = RuntimeTypeAdapterFactory .of(DeviceDef::class.java) .registerSubtype(BluetoothDef::class.java) .registerSubtype(WiFiDef::class.java) val gson = GsonBuilder().setPrettyPrinting().registerTypeAdapterFactory(adapter).create() 
  1. 在工厂注册你的每个亚型,它将按预期工作:)