当前位置: 首页 > 知识库问答 >
问题:

Android:使用Moshi适配器解析内部非结构化Json

邵骏喆
2023-03-14

我很难解析JSON的某些内部部分(使用Moshi),这些内部部分可能变化很大,并且高度非结构化。总体看来是:

response: {
    items: [{
        type: "typeA",
        data: {
            "1563050214700-001": {
                foo: 123 ....
            }
        }
    }, {
        type: "typeB",
        data: {
            "1563050214700-002": {[
                // differs a lot from previous one
                {bar: 123 .... }
            ]}
        }
    }]
}

和数据类结构如下所示:

data class Response(
    val items: Map<String,List<Item?>>?
) {
    data class Item(
        val type: String?,
        val data: Map<String,List<DataItem?>>?
    ) {
        data class DataItem(
            // members highly unstructured
        )
    }
}

“DataItem”的模式变化很大。看起来Moshi codegen支持适配器,可能允许手动解析这些内部数据类,但我没有找到正确的教程或示例。理想情况下,我希望解析整个响应,就像解析一个定义良好的JSON一样。

以下是我如何使用改装/摩什

@Provides
@Singleton
@MyApp
fun provideMyAppRetrofit(context: Context, @MyApp okHttpClient: OkHttpClient): Retrofit {
    return Retrofit.Builder()
        .client(okHttpClient)
        .addConverterFactory(MoshiConverterFactory.create())
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .baseUrl(context.getString(R.string.APP_BASE_URL))
        .build()
}

@Provides
@Singleton
fun provideMyAppApiService(@MyApp retrofit: Retrofit): MyAppApiService {
    return retrofit.create(MyAppApiService::class.java)
}

我如何实现这一点?任何示例或参考实现都将有所帮助。

共有1个答案

羊舌承颜
2023-03-14

欢迎来到多态JSON解析问题Word!

我们编写了自己的JSON适配器,其外观如下:

internal class CardJsonAdapter(
        moshi: Moshi
) : JsonAdapter<Card>() {

    private val cardTypeAdapter = moshi.adapter(Card.Type::class.java)
    private val amountsWithActionAdapter = moshi.adapter(AmountsWithActionCard::class.java)
    private val backgroundImageCardAdapter = moshi.adapter(BackgroundImageCard::class.java)

    @Suppress("TooGenericExceptionCaught")
    override fun fromJson(reader: JsonReader): Card = try {

        @Suppress("UNCHECKED_CAST")
        val jsonMap = reader.readJsonValue() as Map<String, Any?>
        val type = cardTypeAdapter.fromJsonValue(jsonMap["type"])
        createCardWithType(type, jsonMap)

    } catch (error: Exception) {
        if (BuildConfig.DEBUG) {
            Log.w("CardJsonAdapter", "Failed to parse card", error)
        }
        // Try not to break the app if we get unexpected data: ignore errors and return a placeholder card instead.
        UnknownCard
    }

    override fun toJson(writer: JsonWriter, value: Card?) {
        throw NotImplementedError("This adapter cannot write cards to JSON")
    }

    private fun createCardWithType(type: Type?, jsonMap: Map<String, Any?>) = when (type) {
        null -> UnknownCard
        Type.AMOUNTS_WITH_ACTION -> amountsWithActionAdapter.fromJsonValue(jsonMap)!!
        Type.BACKGROUND_IMAGE_WITH_TITLE_AND_MESSAGE -> backgroundImageCardAdapter.fromJsonValue(jsonMap)!!
    }
}

然而,它不再是必需的。Moshi现在支持多态JSON解析-https://proandroiddev.com/moshi-polymorphic-adapter-is-d25deebbd7c5

 类似资料:
  • 我正在尝试使用moshi与我的Android项目,但我遇到了一些问题。 下面是一个精简的JSON示例 如您所见,它是的列表,在该对象中有一个标签和。它是包含3个字段的数组: :用于标识项目类型的字符串标签 :可以是、和类 :,它是更多的列表 因此,第一个问题是有一个列表,每个项都可以有自己的列表,其中包含更多项。 第二个问题是字段,它需要实例化为三个类之一:、和。 我已经在这方面工作了一段时间,到

  • 好了,我有了以下Json POJO: > 基于JProduct内部的某些值 JCategory two列表将合并为1,其中将包含更多的JCategory加上prod1/prod2。 根据Moshi的说法,这是映射适配器中数据的有效和高效的方法吗? 注意,我有一个JCategory,并且在同一个对象的列表中,所以我认为适配器会自动解析它,但它没有。所以我尝试了并成功了。 所以我的问题是: 是处理这种

  • 我使用一个API,它以数组的形式返回数据,比如这个JSON字符串(我们称之为“任务”) 我想将这个响应解析为一个列表。所以我已经用生成的适配器创建了相应的数据类 我的改装服务是这样的 但我想使用容器类型,例如: 作为网络响应结果。这可能不创建自定义adpter或者我将需要创建一个自定义适配器并将其传递给moshi构建器吗?

  • 我有一个NLP任务,我需要确保多个句子的一个段落至少包含一个结构良好的问题,我正在使用OpenNLP生成段落中的解析树。我的问题是: 1-有没有一种方法可以为一个结构合理的问题获取可能的解析树列表。 2.如何比较两个解析树 谢谢

  • 我在我的应用程序中使用了reverfit(V2.9.0)和Moshi(V1.11.0)。我尝试这样调用endpoint: 但是WatchStatus->JSON转换没有像预期的那样工作。WatchStatus是一个简单的枚举类: 我创建了一个自定义适配器,因为我的应用程序使用大写枚举名称,而后端使用小写名称: 我以以下方式创建Moshi实例: 并且我的改型实例使用它(带有Koin注入): 解析Js

  • 根据我对Netty的理解,传入消息传递给eventLoop(只有一个eventLoop,一个线程)。接下来,EventLoop不处理它,而是将其传递给ExecutorService(它在池中保存多个线程)执行。 所有这些都是在NIO的帮助下实现的。EventLoop等待传入消息,并通过选择器、键、通道等传递消息。 我说的对吗? 使用Netty 4