如何用Gson反序列化Jetpack Compose的Color类型?
解决Gson反序列化Compose
Color内联值类的问题 问题根源
Compose的Color是JVM内联值类(@JvmInline value class Color(val value: ULong)),Gson默认会将其视为底层的ULong类型处理,直接绕过针对Color::class.java注册的适配器,导致自定义逻辑不生效;而错误注册Long类型适配器时,又会因类型不匹配抛出异常。
解决方案
以下两种方法均可在不修改字段类型的前提下实现需求:
方案一:全局注册Color类型的层次适配器
使用registerTypeHierarchyAdapter替代普通的registerTypeAdapter,让Gson正确识别内联值类并触发自定义适配器:
fun main() { val gson = GsonBuilder() // 注册Color类型的层次适配器 .registerTypeHierarchyAdapter(Color::class.java, ColorAdapter()) .create() // 注意JSON格式要规范,键名必须用双引号包裹 val colors = gson.fromJson("{\"color\": \"#FFFFFF\"}", Colors::class.java) println(colors) } class ColorAdapter : TypeAdapter<Color>() { override fun write(out: JsonWriter?, value: Color?) { value?.let { out?.value(String.format("#%08X", it.value)) } } override fun read(reader: JsonReader): Color { val colorHex = reader.nextString().removePrefix("#") // 将十六进制字符串转为ULong,适配Color的构造参数类型 val colorValue = colorHex.toULong(radix = 16) return Color(colorValue) } } data class Colors(val color: Color)
方案二:在数据类字段上指定适配器
如果不需要全局适配,可直接在Color字段上添加@JsonAdapter注解,强制Gson使用自定义适配器:
import com.google.gson.annotations.JsonAdapter data class Colors( @JsonAdapter(ColorAdapter::class) val color: Color ) // 适配器和main函数逻辑同方案一
关键注意事项
- 必须使用符合标准的JSON格式,键名必须用双引号包裹(如
{"color": "#FFFFFF"}而非{color: "#FFFFFF"}) - 适配器中要将十六进制字符串转为
ULong,因为Color的构造参数是无符号长整型,避免类型不匹配 - 针对内联值类,
registerTypeHierarchyAdapter比registerTypeAdapter更可靠,能让Gson正确识别目标类型
内容的提问来源于stack exchange,提问作者Милош Којадиновић
相关产品推荐
相关产品推荐

