Gson 反序列化用于合成颜色

问题描述 投票:0回答:1

在我的项目中,我想使用 Gson 反序列化具有 androidx.compose.ui.graphics.Color 的 JSON。我的简化数据类如下所示:

data class Colors(val color: Color)

我想为颜色类型添加自定义适配器:

fun main() {

    val colors = GsonBuilder()
        .registerTypeAdapter(Color::class.java, ColorAdapter())
        .create()
        .fromJson("{color: \"#FFFFFF\"}", Colors::class.java)

    println(colors)
}

class ColorAdapter : TypeAdapter<Color>() {
    override fun write(out: JsonWriter?, value: Color?) {
        TODO("Not yet implemented")
    }

    override fun read(reader: JsonReader): Color {
        val color = reader.nextString()
        return Color(color.removePrefix("#").toLong(radix = 16))
    }
}

它的读取从未被调用,应用程序因格式而崩溃,所以我尝试了其他方法。像这样添加适配器

.registerTypeHierarchyAdapter(Long::class.java, ColorAdapter())

在这种情况下,调用了 read,但发生了错误:线程“main”com.google.gson.JsonSyntaxException 中出现异常:预期很长,但是 androidx.compose.ui.graphics.Color

原因可能在于颜色的定义:

@Immutable
@kotlin.jvm.JvmInline
value class Color(val value: ULong)

但无论如何,我没有找到任何解决方案。

问题是如何在不更改字段和适配器以使用 Long 的情况下完成此操作,因为这是我现在唯一的选择。

android kotlin android-jetpack-compose gson
1个回答
0
投票

还为

Colors
类定义类型适配器似乎可以解决问题。例如,这有效:

package org.example
import androidx.compose.ui.graphics.Color
import com.google.gson.GsonBuilder
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import java.lang.reflect.Type

data class Colors(val color: Color)

fun main() {

    val colors = GsonBuilder()
        .registerTypeAdapter(Colors::class.java, ColorsAdapter())
        .registerTypeAdapter(Color::class.java, ColorAdapter())
        .create()
        .fromJson("{color: \"#FFFFFF\"}", Colors::class.java)

    println(colors)
}

class ColorsAdapter : JsonDeserializer<Colors> {
    override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): Colors {
        return Colors(context!!.deserialize(json!!.asJsonObject.get("color"), Color::class.java))
    }
}

class ColorAdapter : JsonDeserializer<Color> {
    override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): Color {
        return Color(json!!.asString.removePrefix("#").toInt(16))
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.