1

如何通过 Moshi 将 SparseArray 序列化为 JSON?我真的不明白如何为此制作正确的适配器,不胜感激。

编辑:我已通过此代码使其工作

class SparseArrayJsonAdapter : JsonAdapter<SparseArray<WaterWarningItem>>() {
override fun fromJson(reader: JsonReader?): SparseArray<WaterWarningItem> {
    TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}

override fun toJson(writer: JsonWriter?, value: SparseArray<WaterWarningItem>) {
    writer?.let { writer ->
        writer.beginArray()
        for (i in 0 until value.size()) {
            val key = value.keyAt(i)
            val item = value[key]
            writeWarningItem(writer, item)
        }
        writer.endArray()
        writer.close()
    }
}

fun writeWarningItem(writer: JsonWriter, item: WaterWarningItem) {
    writer.beginObject()
    writer.name("id").value(item.id)
    writer.name("title").value(item.title)
    writer.name("warning_lvl").value(item.warningLvl)
    writer.name("own_limit").value(item.ownLimit)
    writer.endObject()
}

}

我像这样使用这个适配器

val a = SparseArrayJsonAdapter()
val json = a.toJson(value)

但我不知道这是否是正确的方式。在所有示例中,适配器都由 moshi builder 附加,但它不适用于我的适配器。这个可以吗?

4

1 回答 1

3

根据您现有的 toJson 实现,这是一个可用于序列化 SparseArrays 的通用版本。

class SparseArrayJsonAdapter(
    private val elementAdapter: JsonAdapter<Any?>) : JsonAdapter<SparseArray<Any?>>() {
  object Factory : JsonAdapter.Factory {
    override fun create(type: Type, annotations: Set<Annotation>,
        moshi: Moshi): JsonAdapter<*>? {
      if (annotations.isNotEmpty()) return null
      val rawType = Types.getRawType(type)
      if (rawType != SparseArray::class.java) return null
      val elementType = (type as ParameterizedType).actualTypeArguments[0]
      return SparseArrayJsonAdapter(moshi.adapter(elementType))
    }
  }

  override fun fromJson(reader: JsonReader): SparseArray<Any?> {
    throw UnsupportedOperationException()
  }

  override fun toJson(writer: JsonWriter, value: SparseArray<Any?>?) {
    checkNotNull(value, { "Adapter doesn't support null. Wrap with nullSafe()." }).apply {
      writer.beginArray()
      var index = 0
      val size = size()
      while (index < size) {
        elementAdapter.toJson(writer, valueAt(index++))
      }
      writer.endArray()
    }
  }
}

data class WaterWarningItem(val id: Long, val title: String, val warning_lvl: String,
    val own_limit: String)

fun main(args: Array<String>) {
  val moshi = Moshi.Builder().add(SparseArrayJsonAdapter.Factory).build()
  val adapter = moshi.adapter<SparseArray<WaterWarningItem>>(
      Types.newParameterizedType(SparseArray::class.java, WaterWarningItem::class.java))
  val result = adapter.toJson(SparseArray<WaterWarningItem>(1).apply {
    put(7, WaterWarningItem(5L, "Hello", "Fine", "Okay"))
  })
}
于 2018-04-02T18:30:59.537 回答