How can I serialize SparseArray to JSON by Moshi? I really don't understand how to make right adapter for this, any help is appreciated.
EDIT: I've made it work by this code
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()
}
}
I use this adapter like
val a = SparseArrayJsonAdapter()
val json = a.toJson(value)
But I dont't know if this is right way. Adapter are attached by moshi builder in all examples, but it doesn't work with my adapter. Is this ok?
Based on your existing toJson implementation, this is a generic version you can use for serializing your 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"))
})
}