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

Moshi+Kotlin+SealedClass

邓卓
2023-03-14

是否有一种方法可以使用

sealed class Layer

data class ShapeLayer(var type: LayerType) : Layer
data class TextLayer(var type: LayerType) : Layer
data class ImageLayer(var type: LayerType) : Layer

LayerType只是一些枚举,可以用来区分该对象应该具有哪种类型。

class LayerAdapter{
    @FromJson
    fun fromJson(layerJson: LayerJson): Layer {
        return when (layerJson.layerType) {
            LayerType.SHAPE -> PreCompLayer()
            LayerType.SOLID -> SolidLayer()
            LayerType.Text -> TextLayer()
        }
    }
}

无法序列化抽象类com.example.models.layers.layer

我可以尝试使用接口,但我不认为这将是正确的使用空接口。

共有1个答案

幸阳波
2023-03-14

是的,您可以创建一个自定义类型适配器来根据layertype解析json,如下所示:

class LayerAdapter {
    @FromJson
    fun fromJson(layerJson: LayerJson): Layer = when (layerJson.layerType) {
        LayerType.SHAPE -> ShapeLayer(layerJson.layerType, layerJson.shape ?: "")
        LayerType.TEXT -> TextLayer(layerJson.layerType, layerJson.text ?: "")
        LayerType.IMAGE -> ImageLayer(layerJson.layerType, layerJson.image ?: "")
    }

    @ToJson
    fun toJson(layer: Layer): LayerJson = when (layer) {
        is ShapeLayer -> LayerJson(layer.type, shape = layer.shape)
        is TextLayer -> LayerJson(layer.type, text = layer.text)
        is ImageLayer -> LayerJson(layer.type, image = layer.image)
        else -> throw RuntimeException("Not support data type")
    }
}

为了清晰起见,我在这里对数据类做了一些更改(每个类型的额外属性,例如ShapeLayerShapeLayerShapeLayer的ShapeLayer):

sealed class Layer

data class ShapeLayer(val type: LayerType, val shape: String) : Layer()
data class TextLayer(val type: LayerType, val text: String) : Layer()
data class ImageLayer(val type: LayerType, val image: String) : Layer()

//LayerJson contains every possible property of all layers
data class LayerJson(val layerType: LayerType, val shape: String? = null, val text: String? = null, val image: String? = null) : Layer()

enum class LayerType {
    SHAPE, TEXT, IMAGE
}

测试代码:

val moshi = Moshi.Builder()
        .add(LayerAdapter())
        .build()
val type = Types.newParameterizedType(List::class.java, Layer::class.java)
val adapter = moshi.adapter<List<Layer>>(type)

//Convert from json string to List<Layer>
val layers: List<Layer>? = adapter.fromJson("""
    [
        {"layerType":"SHAPE", "shape":"I am rectangle"},
        {"layerType":"TEXT", "text":"I am text"},
        {"layerType":"IMAGE", "image":"I am image"}
    ]
""".trimIndent())
layers?.forEach(::println)

//Convert a list back to json string
val jsonString: String = adapter.toJson(layers)
println(jsonString)
ShapeLayer(type=SHAPE, shape=I am rectangle)
TextLayer(type=TEXT, text=I am text)
ImageLayer(type=IMAGE, image=I am image)
[{"layerType":"SHAPE","shape":"I am rectangle"},{"layerType":"TEXT","text":"I am text"},{"image":"I am image","layerType":"IMAGE"}]

编辑:当您试图解析包含的其他对象时,可以像往常一样添加适配器。假设您有这样一个对象:

data class LayerContainer(val layers: List<Layer>)

测试代码:

val moshi = Moshi.Builder()
        .add(LayerAdapter())
        .build()

val adapter = moshi.adapter(LayerContainer::class.java)
val layerContainer: LayerContainer? = adapter.fromJson("""
    {
        "layers": [
            {"layerType":"SHAPE", "shape":"I am rectangle"},
            {"layerType":"TEXT", "text":"I am text"},
            {"layerType":"IMAGE", "image":"I am image"}
        ]
    }
""".trimIndent())
layerContainer?.layers?.forEach(::println)

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

  • 在为Android项目配置Kotlin之后,我编写了一个简单的。它调用了reverfit来获得一个包含以下数据的JSON文件: 现在我想使用Moshi将JSON数据转换为Kotlin的类,所以下面是反映上述JSON结构的两个类: 和Moshi的自定义类型适配器: 当它进入函数时,就像预期的那样。但奇怪的是,是,应该是。 我对莫希和科特林是新的,我已经在这个问题上坚持了大约10个小时。请帮帮我。谢谢

  • [{“id”:1,“first_name”:“Lillis”,“last_name”:“Hawgood”,“cars”:[{“item”:“Savana 1500”},{“item”:“Vibe”},{“item”:“Estate”}]}] 数据类MyData(val id:Int=0,val first_name:String=“”,val last_name:String=“”,val car

  • 我在用Moshi注释设置我的领域实例时遇到了一个问题。还没有发现类似的问题。 下面的模型类 和收到的错误 提前感谢您的任何帮助:)

  • 如何在Android kotlin、Moshi和Regetfit中解析嵌套动态键的嵌套JSON? 我从Alpha-Vantage获得这个JSON。