I'm trying to convert a Java object to JSON using the Moshi library for Android. The object contains a property of type
ArrayList < float[]>
and I'm registering the following adapter to convert the object.
Type type = Types.newParameterizedType
(List.class, HistoryPath.class, ArrayList.class, Float[].class, Float.class);
JsonAdapter<Drawing> adapter = moshi.adapter(type);
String json = adapter.toJson(drawing);
The "toJson" method fails with the following exception:
java.lang.IllegalArgumentException: Platform java.util.ArrayList annotated [] requires explicit JsonAdapter to be registered at com.squareup.moshi.ClassJsonAdapter$1.create(ClassJsonAdapter.java:50) at com.squareup.moshi.Moshi.adapter(Moshi.java:99) at com.squareup.moshi.ClassJsonAdapter$1.createFieldBindings(ClassJsonAdapter.java:90) at com.squareup.moshi.ClassJsonAdapter$1.create(ClassJsonAdapter.java:74) at com.squareup.moshi.Moshi.adapter(Moshi.java:99) at com.squareup.moshi.ClassJsonAdapter$1.createFieldBindings(ClassJsonAdapter.java:90) at com.squareup.moshi.ClassJsonAdapter$1.create(ClassJsonAdapter.java:74) at com.squareup.moshi.Moshi.adapter(Moshi.java:99) at com.squareup.moshi.Moshi.adapter(Moshi.java:57) at com.squareup.moshi.CollectionJsonAdapter.newArrayListAdapter(CollectionJsonAdapter.java:51) at com.squareup.moshi.CollectionJsonAdapter$1.create(CollectionJsonAdapter.java:35) at com.squareup.moshi.Moshi.adapter(Moshi.java:99) at com.squareup.moshi.Moshi.adapter(Moshi.java:57)
I think my type definitions are wrong but I can't seem to find the right value
Moshi is a modern JSON library for Android and Java from Square. It can be considered as the successor to GSON, with a simpler and leaner API and an architecture enabling better performance through the use of the Okio library.
Moshi is a modern JSON library for Android, Java and Kotlin. It makes it easy to parse JSON into Java and Kotlin classes: Note: The Kotlin examples of this README assume use of either Kotlin code gen or KotlinJsonAdapterFactory for reflection.
ArrayList is a platform type, as the error says. You can use List (or make a custom JsonAdapter specifically for ArrayList).
Also, there's a problem here:
Type type = Types.newParameterizedType(List.class, HistoryPath.class, ArrayList.class, Float[].class, Float.class);
This type is List<HistoryPath, ArrayList, Float[], Float>
which is invalid, and it will not yield the correct result for JsonAdapter<Drawing> adapter = moshi.adapter(type);
.
You probably just want JsonAdapter<Drawing> adapter = moshi.adapter(Drawing.class);
.
Those who want to use ArrayList
and Moshi
You have to make adapters for every object you want to use.
class ThingArrayListMoshiAdapter {
@ToJson
fun arrayListToJson(list: ArrayList<Thing>): List<Thing> = list
@FromJson
fun arrayListFromJson(list: List<Thing>): ArrayList<Thing> = ArrayList(list)
}
usage
Moshi
.Builder()
.add(ThingArrayListMoshiAdapter())
.build()
Make a JsonAdapter
for ArrayList
, like Moshi's CollectionJsonAdapter
abstract class MoshiArrayListJsonAdapter<C : MutableCollection<T>?, T> private constructor(
private val elementAdapter: JsonAdapter<T>
) :
JsonAdapter<C>() {
abstract fun newCollection(): C
@Throws(IOException::class)
override fun fromJson(reader: JsonReader): C {
val result = newCollection()
reader.beginArray()
while (reader.hasNext()) {
result?.add(elementAdapter.fromJson(reader)!!)
}
reader.endArray()
return result
}
@Throws(IOException::class)
override fun toJson(writer: JsonWriter, value: C?) {
writer.beginArray()
for (element in value!!) {
elementAdapter.toJson(writer, element)
}
writer.endArray()
}
override fun toString(): String {
return "$elementAdapter.collection()"
}
companion object {
val FACTORY = Factory { type, annotations, moshi ->
val rawType = Types.getRawType(type)
if (annotations.isNotEmpty()) return@Factory null
if (rawType == ArrayList::class.java) {
return@Factory newArrayListAdapter<Any>(
type,
moshi
).nullSafe()
}
null
}
private fun <T> newArrayListAdapter(
type: Type,
moshi: Moshi
): JsonAdapter<MutableCollection<T>> {
val elementType =
Types.collectionElementType(
type,
MutableCollection::class.java
)
val elementAdapter: JsonAdapter<T> = moshi.adapter(elementType)
return object :
MoshiArrayListJsonAdapter<MutableCollection<T>, T>(elementAdapter) {
override fun newCollection(): MutableCollection<T> {
return ArrayList()
}
}
}
}
}
usage
Moshi
.Builder()
.add(MoshiArrayListJsonAdapter.FACTORY)
.build()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With