I can use Code 1 to save MutableList<MDetail>
to json string using Gson correctly,
But I get the error when I try to restore MutableList<MDetail>
object from json string with Code 2.
I have search some resources, it seems that I need to register an InstanceCreator.
How can I write a register an InstanceCreator
code with Kotlin? Thanks!
Error
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.
Code 1
private var listofMDetail: MutableList<MDetail>?=null
mJson = Gson().toJson(listofMDetail) //Save
Code 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)
My Class
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()
}
}
Added
After I use val myGson = GsonBuilder().setPrettyPrinting().registerTypeAdapterFactory(adapter).create()
, I can get the correct result when I use open class DeviceDef
, why?
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()