Как зарегистрировать InstanceCreator с Gson в Котлине?

Я могу использовать код 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> . Вот что вам нужно сделать:

  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. зарегистрируйте каждый из ваших подтипов на заводе, и он будет работать по назначению 🙂