Android莫希无法应用自定义适配器

umuewwlo  于 2023-04-04  发布在  Android
关注(0)|答案(1)|浏览(116)

我的用例是,在数据类中,无论我在何处使用Boolean作为类型,在JSON中,可以作为双引号字符串(“true”)或普通Boolean(true)
之前我使用的是Gson &它可以自动处理所有这些情况,但是当我尝试迁移到莫希时,我遇到了很多问题

class BooleanAdapter : JsonAdapter<Boolean>() {
    @FromJson
    override fun fromJson(reader: JsonReader): Boolean {
        return when (reader.peek()) {
            JsonReader.Token.BOOLEAN -> reader.nextBoolean()
            JsonReader.Token.STRING -> {
                when (val value = reader.nextString()) {
                    "true", "True", "TRUE", "1" -> true
                    "false", "False", "FALSE", "0" -> false
                    else -> throw JsonDataException("Invalid boolean value: $value")
                }
            }
            JsonReader.Token.NUMBER -> {
                when (val value = reader.nextInt()) {
                    0 -> false
                    1 -> true
                    else -> throw JsonDataException("Invalid boolean value: $value")
                }
            }
            else -> throw JsonDataException("Expected boolean or string or int value but was ${reader.peek()}")
        }
    }

    @ToJson
    override fun toJson(writer: JsonWriter, value: Boolean?) {
        writer.value(value)
    }
}

然后用这个给莫希注射改造

@Singleton
@Provides
@MoshiBuilder
fun providesDeserializer(): Moshi =
    Moshi.Builder()
        .add(BooleanAdapter())
        .build()

下面是一个示例数据类

@JsonClass(generateAdapter = true)
data class ItemResponse(

    @field:JsonAdapter(BooleanAdapter::class)
    @Json(name = "mSet") val IsSet: Boolean,

    @Json(name = "name") val name: String,

    @field:JsonAdapter(BooleanAdapter::class)
    @Json(name = "isPrimary") val isPrimary: Boolean
)

获取以下错误

com.squareup.moshi.JsonDataException: Expected a boolean but was STRING at path

在JSON中,此参数为“true”
我错过了什么。看来我做了一个错误的选择迁移到莫希

dauxcl2d

dauxcl2d1#

删除JsonAdapter继承。ToJson和FromJson注解不需要继承,但实际上会导致Kotlin和装箱原始类型的微妙问题。
通过扩展JsonAdapter,您正在为盒装类型Boolean创建适配器,而不是原始类型boolean,但是您的ItemResponse声明了原始布尔类型,因此莫希查找原始类型的适配器,而不是您拥有适配器的盒装类型。
要获得想要的结果,只需确保适配器是用于基本布尔类型。

class BooleanAdapter {
  @FromJson
  fun fromJson(reader: JsonReader): Boolean {
    return when (reader.peek()) {
      JsonReader.Token.BOOLEAN -> reader.nextBoolean()
      JsonReader.Token.STRING -> {
        when (val value = reader.nextString()) {
          "true", "True", "TRUE", "1" -> true
          "false", "False", "FALSE", "0" -> false
          else -> throw JsonDataException("Invalid boolean value: $value")
        }
      }
      JsonReader.Token.NUMBER -> {
        when (val value = reader.nextInt()) {
          0 -> false
          1 -> true
          else -> throw JsonDataException("Invalid boolean value: $value")
        }
      }
      else -> throw JsonDataException("Expected boolean or string or int value but was ${reader.peek()}")
    }
  }

  @ToJson
  fun toJson(writer: JsonWriter, value: Boolean?) {
    writer.value(value)
  }
}
Moshi.Builder().add(BooleanAdapter()).build()

相关问题