Создать TypeAdapterFactory для привязки данных ObservableField - PullRequest
0 голосов
/ 04 декабря 2018

Я использую ObservableField для привязки данных и хочу десериализовать с помощью GSON.

class Foo: Observable {
   var bar: ObservableField<String>? = null
}

Если я не предоставлю TypeAdapter, GSON попытается десериализовать как объект вместо строки.

Моя фабрика адаптеров типа и адаптер типа:

class ObservableFieldTypeAdapterFactory: TypeAdapterFactory {
    override fun <T> create(gson: Gson, type: TypeToken<T>): TypeAdapter<T>? {
        if (type.rawType != ObservableField::class.java) {
            return null
        }

        return object : TypeAdapter<ObservableField<Any>>() {
            override fun read(reader: JsonReader): ObservableField<Any> {
              // get the generic type of the ObservableField and let GSON 
              // deserialize it
              val field = someDelegate.read(reader)
              // wrap it
              return ObservableField(field)
            }

            override fun write(out: JsonWriter?, value: ObservableField<Any>) {
                throw UnsupportedOperationException()
            }
        }.nullSafe() as TypeAdapter<T>
    }
}

Я не знаю, как сказать GSON для анализа универсального типа ObservableField:

// get the generic type of the ObservableField and let GSON deserialize it
val field = someDelegate.read(reader)

Как мне делегировать GSON для анализа поля String, чтобы я мог обернуть его?Я могу проверить, является ли это строковым полем, но тогда этот адаптер не поддерживает Ints или какой-либо универсальный объект.

Нужно ли проверять тип поля, считываемого с помощью peek?А затем включить каждый тип поля с соответствующим удалением?

1 Ответ

0 голосов
/ 05 декабря 2018

На самом деле type должен реализовывать ParameterizedType, и вам нужно получить первый элемент actualTypeArguments, чтобы получить адаптер для универсального типа:

override fun <T> create(gson: Gson, type: TypeToken<T>): TypeAdapter<T>? {
    if (type.rawType != ObservableField::class.java) {
        return null
    }

    val paramType = (type as ParameterizedType).actualTypeArguments[0]
    return object : TypeAdapter<ObservableField<Any>>() {
        override fun read(reader: JsonReader): ObservableField<Any> {
          return ObservableField(gson.fromJson(reader, paramType))
        }

        override fun write(writer: JsonWriter, value: ObservableField<Any>) {
            gson.toJson(value.get(), paramType, writer)
        }
    }.nullSafe() as TypeAdapter<T>
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...