【问题标题】:How to serialize ArrayList<float[]> using Moshi JSON library for Android如何使用 Moshi JSON 库为 Android 序列化 ArrayList<float[]>
【发布时间】:2017-10-06 18:41:19
【问题描述】:

我正在尝试使用适用于 Android 的 Moshi 库将 Java 对象转换为 JSON。该对象包含一个

类型的属性

数组列表

我正在注册以下适配器来转换对象。

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);

“toJson”方法失败,出现以下异常:

java.lang.IllegalArgumentException:平台 java.util.ArrayList annotated [] 需要显式 要注册的 JsonAdapter 在 com.squareup.moshi.ClassJsonAdapter$1.create(ClassJsonAdapter.java:50) 在 com.squareup.moshi.Moshi.adapter(Moshi.java:99) 在 com.squareup.moshi.ClassJsonAdapter$1.createFieldBindings(ClassJsonAdapter.java:90) 在 com.squareup.moshi.ClassJsonAdapter$1.create(ClassJsonAdapter.java:74) 在 com.squareup.moshi.Moshi.adapter(Moshi.java:99) 在 com.squareup.moshi.ClassJsonAdapter$1.createFieldBindings(ClassJsonAdapter.java:90) 在 com.squareup.moshi.ClassJsonAdapter$1.create(ClassJsonAdapter.java:74) 在 com.squareup.moshi.Moshi.adapter(Moshi.java:99) 在 com.squareup.moshi.Moshi.adapter(Moshi.java:57) 在 com.squareup.moshi.CollectionJsonAdapter.newArrayListAdapter(CollectionJsonAdapter.java:51) 在 com.squareup.moshi.CollectionJsonAdapter$1.create(CollectionJsonAdapter.java:35) 在 com.squareup.moshi.Moshi.adapter(Moshi.java:99) 在 com.squareup.moshi.Moshi.adapter(Moshi.java:57)

我认为我的类型定义是错误的,但我似乎找不到正确的值

【问题讨论】:

    标签: moshi


    【解决方案1】:

    ArrayList 是一种平台类型,如错误所述。 您可以使用 List(或专门为 ArrayList 制作自定义 JsonAdapter)。

    另外,这里有一个问题: Type type = Types.newParameterizedType(List.class, HistoryPath.class, ArrayList.class, Float[].class, Float.class);

    这个类型是List&lt;HistoryPath, ArrayList, Float[], Float&gt;,它是无效的,它不会为JsonAdapter&lt;Drawing&gt; adapter = moshi.adapter(type);产生正确的结果。

    你可能只想要JsonAdapter&lt;Drawing&gt; adapter = moshi.adapter(Drawing.class);

    【讨论】:

    • 根据您的建议得到一个不同的错误:ArrayList annotated [] 需要显式注册 JsonAdapter
    • @androidguy ArrayList 是一个平台类型。你需要为它注册一个JsonAdapter,或者使用List。
    【解决方案2】:

    想用ArrayList和Moshi的人


    解决方案 1

    您必须为要使用的每个对象制作适配器。

    class ThingArrayListMoshiAdapter {
        @ToJson
        fun arrayListToJson(list: ArrayList<Thing>): List<Thing> = list
    
        @FromJson
        fun arrayListFromJson(list: List<Thing>): ArrayList<Thing> = ArrayList(list)
    }
    

    用法

    Moshi
        .Builder()
        .add(ThingArrayListMoshiAdapter())
        .build()
    

    解决方案 2

    ArrayList 创建一个JsonAdapter,就像Moshi 的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()
                    }
                }
            }
        }
    }
    

    用法

    Moshi
        .Builder()
        .add(MoshiArrayListJsonAdapter.FACTORY)
        .build()
    

    【讨论】:

      【解决方案3】:

      将其转换为数组。

      假设您想使用arraylist : ArrayList&lt;&gt;。您将其转换为数组。 arraylist.toArray()

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-04
        • 1970-01-01
        • 2020-10-31
        • 2014-04-12
        • 1970-01-01
        • 2012-04-07
        • 2017-04-18
        • 1970-01-01
        相关资源
        最近更新 更多