如何使用Moshi序列化SparseArray

时间:2018-03-27 15:36:46

标签: android moshi

如何通过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附加,但它不适用于我的适配器。 这可以吗?

1 个答案:

答案 0 :(得分:2)

根据您现有的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"))
  })
}