Я могу использовать код 1, чтобы сохранить MutableList<MDetail>
в json string, используя Gson правильно, но я получаю ошибку, когда пытаюсь восстановить MutableList<MDetail>
из строки json с кодом 2. У меня есть поиск некоторых ресурсов, кажется, что я необходимо зарегистрировать экземпляр InstanceCreator.
Как я могу написать регистр InstanceCreator
кодом 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()
Gson испытывает трудности с десериализацией полиморфных объектов, как в вашем MutableList<DeviceDef>
. Вот что вам нужно сделать:
Добавьте RuntimeTypeAdapterFactory.java в свой проект вручную (он, похоже, не является частью библиотеки gson ). См. Также этот ответ .
Измените свой код на использование фабрики
Создать экземпляр Gson
:
val adapter = RuntimeTypeAdapterFactory .of(DeviceDef::class.java) .registerSubtype(BluetoothDef::class.java) .registerSubtype(WiFiDef::class.java) val gson = GsonBuilder().setPrettyPrinting().registerTypeAdapterFactory(adapter).create()