具有泛型类型的Android和Moshi适配器

具有泛型类型的Android和Moshi适配器,android,kotlin,retrofit2,moshi,Android,Kotlin,Retrofit2,Moshi,我试图在我的Android项目中使用moshi,但我遇到了一些问题 下面是一个简化的JSON示例 { "data": [ { "label": "May", "schedule_items": [ { "type": "event", "item": { "foo": "bar", "some_prop": 1 },

我试图在我的Android项目中使用moshi,但我遇到了一些问题

下面是一个简化的JSON示例

{
  "data": [
    {
      "label": "May",
      "schedule_items": [
        {
          "type": "event",
          "item": {
            "foo": "bar",
            "some_prop": 1
          },
          "schedule_item_groups": [
            {
              "label": "Friday May 4th",
              "schedule_items": [
                {
                  "type": "check_in",
                  "item": {
                    "a_different_prop": 15
                  },
                  "schedule_item_groups": null
                },
                {
                  "type": "game",
                  "item": {
                    "yet_another_different_prop": 3598
                  },
                  "schedule_item_groups": null
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}
如您所见,它是一个ScheduleGroup列表,在该对象中有一个标签和schedule_项。这是一个包含3个字段的ScheduleItem数组:

类型:字符串标签,用于标识此项目的类型 物品:可以是类事件、游戏和签入 schedule_item_groups:一个ScheduleGroup,它是多个项目的列表- 计划项目 所以第一个问题是ScheduleGroup有一个ScheduleItems列表,每个项目都可以有自己的ScheduleGroup列表,其中包含更多的项目

第二个问题是项目字段,它需要实例化为三个类之一:事件、游戏、签入

我已经做了一段时间了,到目前为止,我一次只能做一个,但不能同时做两个

以下是我只包含其中一个项目类的数据类:

它将正确地创建正确的Item类,但是当我尝试添加列表时,我会出现错误,并且无论我做什么,我似乎都无法使这两个类都起作用

编辑:

我已经更新了代码,以显示我正在使用什么来尝试和反序列化schedule_item_组,这是一个列表

我得到一个错误:这是一个不同的错误比我以前得到

com.squareup.moshi.JsonDataException:java.lang.IllegalArgumentException:无法将最终的java.lang.String字段com.room花名册.mobile\u android.data.api.ScheduleGroup.label设置为com.squareup.moshi.LinkedHashTreeMap,地址为$.data[0]。计划项[1]


我一段时间前就发现了这一点,但我想我可以发布我所做的,以防将来对任何人都有帮助

首先,我创建了一个临时中间类,在生成泛型数据之前保存数据

data class ScheduleItem<T>(
    val date: Date,
    val type: String,
    var scheduleGroups: List<ScheduleGroup> = listOf(),
    var item: T
) {
    data class ScheduleItemJson(
        val date: Date,
        val type: String,
        val schedule_item_groups: List<ScheduleGroup>? = listOf(),
        val item: Any
    )
}
然后在适配器中

@FromJson fun fromJson(item: ScheduleItem.ScheduleItemJson): ScheduleItem<Any> {
    val moshi: Moshi = Moshi.Builder().build()
    val json = moshi.adapter(Map::class.java).toJson(item.item as Map<*, *>)

    return ScheduleItem(
        item.date,
        item.type,
        item.schedule_item_groups ?: listOf(),
        when (item.type) {
            ItemType.GAME -> moshi.adapter(GameItem::class.java).fromJson(json)
            ItemType.EVENT -> moshi.adapter(EventItem::class.java).fromJson(json)
            ItemType.CHECK_IN, ItemType.CHECK_OUT ->
                moshi.adapter(ReservationItem::class.java)
                     .fromJson(json).apply { this!!.type = item.type }
            else -> ScheduleItem.NullItem()
        }!!
    )
}

when语句是创建并将其传递给ScheduleItem构造函数的语句。

我不久前就明白了这一点,但我想我可以发布我所做的,以防将来对任何人都有帮助

首先,我创建了一个临时中间类,在生成泛型数据之前保存数据

data class ScheduleItem<T>(
    val date: Date,
    val type: String,
    var scheduleGroups: List<ScheduleGroup> = listOf(),
    var item: T
) {
    data class ScheduleItemJson(
        val date: Date,
        val type: String,
        val schedule_item_groups: List<ScheduleGroup>? = listOf(),
        val item: Any
    )
}
然后在适配器中

@FromJson fun fromJson(item: ScheduleItem.ScheduleItemJson): ScheduleItem<Any> {
    val moshi: Moshi = Moshi.Builder().build()
    val json = moshi.adapter(Map::class.java).toJson(item.item as Map<*, *>)

    return ScheduleItem(
        item.date,
        item.type,
        item.schedule_item_groups ?: listOf(),
        when (item.type) {
            ItemType.GAME -> moshi.adapter(GameItem::class.java).fromJson(json)
            ItemType.EVENT -> moshi.adapter(EventItem::class.java).fromJson(json)
            ItemType.CHECK_IN, ItemType.CHECK_OUT ->
                moshi.adapter(ReservationItem::class.java)
                     .fromJson(json).apply { this!!.type = item.type }
            else -> ScheduleItem.NullItem()
        }!!
    )
}

when语句是创建并将其传递给ScheduleItem构造函数的语句。

最近我遇到了类似的问题,我使用密封类和JsonAdapter动态构建模型。
我在另一篇文章中发布了我的答案,请参见最近我遇到了类似的问题,我使用密封类和JsonAdapter动态构建模型。
我在另一篇帖子中发布了我的答案,请参见

你能发布你得到的错误吗?我已经添加了我正在使用的代码和错误。你可能可以从中进行一些调整,我们将在将来获得关于此用例的更好文档。你能发布你得到的错误吗?我已经添加了我正在使用的代码,还有错误。您可能能够从我们将来将得到关于这个用例的更好的文档中获得一些东西。