我可以使用代码1正确地使用Gson将MutableList<MDetail>
保存到json字符串,
但是当我尝试使用代码2从json字符串恢复MutableList<MDetail>
对象时,我收到错误。
我搜索了一些资源,似乎我需要注册一个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<MDetail>?=null
mJson = Gson().toJson(listofMDetail) //Save
代码2
var mJson: String by PreferenceTool(this, getString(R.string.SavedJsonName) , "")
var aMListDetail= Gson().fromJson<MutableList<MDetail>>(mJson)
inline fun <reified T> Gson.fromJson(json: String) = this.fromJson<T>(json, object: TypeToken<T>() {}.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<DeviceDef>)
{
inline fun <reified T> 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<DeviceDef>)
{
inline fun <reified T> getDevice(): T {
return deviceList.filterIsInstance(T::class.java).first()
}
}
val myGson = GsonBuilder().setPrettyPrinting().registerTypeAdapterFactory(adapter).create()
答案 0 :(得分:3)
Gson很难像你的MutableList<DeviceDef>
那样反序列化多态对象。这是你需要做的:
手动将RuntimeTypeAdapterFactory.java添加到项目中(似乎不是part of gson library)。另请参阅此answer。
更改您的代码以使用工厂
创建Gson
实例:
val adapter = RuntimeTypeAdapterFactory
.of(DeviceDef::class.java)
.registerSubtype(BluetoothDef::class.java)
.registerSubtype(WiFiDef::class.java)
val gson = GsonBuilder().setPrettyPrinting().registerTypeAdapterFactory(adapter).create()
在工厂注册您的每个子类型,它将按预期工作:)