创建用于数据绑定ObservableField的TypeAdapterFactory

时间:2018-12-04 19:12:37

标签: generics kotlin gson

我正在使用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 :(得分:0)

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>
}