Moshi:如何在配置 Moshi.Builder 时为 PolymorphicJsonAdapterFactory.withFallbackJsonAdapter 提供适配器

ytR*_*ino 7 android json moshi

我正在尝试使用PolymorphicJsonAdapterFactoryJSON,它根据type字段提供不同的结构,如下所示。

{
  "notifications": [
    {
      "type": "achievement",
      "title": "New Achievement!",
      "content": "You got new achievement Level 100! (100pt)"
      "metadata": {
        "category": "level",
        "id": "level100",
        "points": 100,
      }
    },
    {
      "type": "message",
      "name": "message",
      "content": "Cloud: hello, ~"
      "metadata": {
        "from": "Cloud",
        "content": "hello, ~ "
      }
    },
    {
      "type": "new", <--- e.g. this is unknown type for app
      "name": "something new",
      "content": "You are informed something about. Please check app://~",
      "deeplink": "app://~"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

假设我们的应用程序已经为一些已知的type,achievement和做好了准备message。但在本例中,有机会添加新类型new。此时,我们希望应用程序能够使用最少的属性titlecontent. 简而言之,我想将该new类型映射到Other后备类。

data class Notifications(
    val notifications: List<Notification>
)

sealed class Notification {
    abstract val type: String
    abstract val title: String
    abstract val content: String
}

data class Achievement(
    override val type: String,
    override val title: String,
    override val content: String,
    val metadata: Metadata,
): Notification() {
    data class Metadata(
        val category: String,
        val id: String,
        val points: Int,
    )
}

data class Message(
    override val type: String,
    override val title: String,
    override val content: String,
    val metadata: Metadata,
): Notification() {
    data class Metadata(
        val from: String,
        val content: String,
    )
}

// Any unknown `type` goes here.
data class Other(
    override val type: String,
    override val title: String,
    override val content: String,
): Notification()

val moshi = Moshi.Builder()
    .add(
        PolymorphicJsonAdapterFactory.of(Notification::class.java, "type")
            .withSubtype(Achievement::class.java, "achievement")
            .withSubtype(Message::class.java, "message")
            .withFallbackJsonAdapter(...)
    )
    .addLast(KotlinJsonAdapterFactory())
    .build()
Run Code Online (Sandbox Code Playgroud)

如果moshi配置Notification这么简单的话,就可以写了.withFallbackJsonAdapter(object: Adapter()...)

但是,如果我们在 中进行了一些自定义Moshi.Builder,我们可能希望使用已配置的 moshi 中的适配器val adapter = moshi.adapter(),因此我们无法内联编写适配器。然后,我想创建两个这样的莫西。

val moshiWithoutPoly = Moshi.Builder()
    // some other base configuration going here
    .build()

val moshi = moshiWithoutPoly.newBuilder()
    .add(
        PolymorphicJsonAdapterFactory.of(Notification::class.java, "type")
            .withSubtype(Achievement::class.java, "achievement")
            .withSubtype(Message::class.java, "message")
            .withFallbackJsonAdapter(moshiWithoutPoly.adapter(Other::class.java) as JsonAdapter<Any>)
    )
    .build()
Run Code Online (Sandbox Code Playgroud)

可以吗?或者有更合适的解决方案吗?
(或者我想知道它是否有资格提出类似.withFallbackSubtype(Other::class.java).withFallbackAdapterFactory(factory)针对这种情况的新 API。)