Kotlinx.serialization 使用指南

引言:为什么需要新的序列化方案?

在 Android / Kotlin 项目中,我们习惯于用 Gson/Moshi 来处理 JSON,但随着业务扩大,我们遇到:

问题 表现
❌ 反射慢、包体大 冷启动有明显反射开销,尤其 fragment/activity 初始化
❌ 字段兼容差 后端新增字段 → JsonSyntaxException
❌ 多态类难处理 sealed class 支持不友好
❌ 配置分散 需要在 Model 或 Adapter 注册序列化逻辑

Kotlinx.serialization 的出现就是为了解决这些痛点。

Kotlinx.serialization 是什么?

一句话定义:

Kotlin 官方提供的 编译期序列化框架,支持 JSON、ProtoBuf、CBOR,跨 JVM / Android / KMM。

特性总结:

✅ 无反射,编译期生成序列化器

✅ Kotlin-first,支持 data/sealed class

✅ 支持多格式 JSON / Protobuf / CBOR

✅ 可与 Ktor / Retrofit 无缝集成

✅ 更轻量小包体,不需要 keep 反射 class

基本用法(3 行代码)

Kotlin 复制代码
@Serializable
data class User(val id: Long, val name: String)

val json = Json { ignoreUnknownKeys = true }

val str = json.encodeToString(User(1, "Ling"))
val u   = json.decodeFromString<User>(str)

重点:必须加 @Serializable,编译期自动生成序列化器,不用反射。

JSON 配置建议(够用就这个)

Kotlin 复制代码
val JSONx = Json {
    ignoreUnknownKeys = true   // 多字段容错
    encodeDefaults = false     // 不把默认值写入JSON
    explicitNulls = false      // 不输出 null 字段
    isLenient = true           // 宽松解析
    coerceInputValues = true   // 类型不匹配挽救
}

开启 ignoreUnknownKeys=true 后,后端新增字段不会炸。

常用注解(70% 的问题靠这些解决)

注解 功能
@SerialName("xxx") JSON key 映射
@JsonNames("a","b") 后端字段不统一时兼容多个
@Transient 不序列化某字段
@Contextual 第三方类,如 UUID、Date
@Serializable(with=...) 自定义序列化器

多态对象(sealed class 最爽)

Kotlin 复制代码
@Serializable
sealed class Message {
   @Serializable @SerialName("text")
   data class Text(val content: String): Message()

   @Serializable @SerialName("image")
   data class Image(val url: String): Message()
}

val json = Json { classDiscriminator = "type" }

输出 JSON:

{"type":"text","content":"hello"}

sealed + classDiscriminator = 强无敌。

tips:

Kotlinx.serialization 对多态对象(sealed class )支持更好用

自定义序列化器(处理后端不稳定 JSON)

例子:后端返回 "timestamp": "1738918293128"(字符串)

Kotlin 复制代码
object EpochMilliAsString : KSerializer<Long> {
    override val descriptor = PrimitiveSerialDescriptor("Epoch", PrimitiveKind.STRING)
    override fun serialize(encoder: Encoder, value: Long) =
       encoder.encodeString(value.toString())
    override fun deserialize(decoder: Decoder) =
       decoder.decodeString().toLong()
}

Retrofit/Ktor 集成(推荐)

Retrofit

Kotlin 复制代码
val json = Json {
    ignoreUnknownKeys = true
    // 过渡期若按内容判别:无需 classDiscriminator
    // 将来有 type:classDiscriminator = "type"
}

val retrofit = Retrofit.Builder()
    .baseUrl("https://api.example.com/")
    .addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
    .build()

interface Api {
    @GET("messages")
    suspend fun list(): List<Message>
}

Ktor Client

Kotlin 复制代码
val client = HttpClient(OkHttp) {
    install(ContentNegotiation) { json(Json {
        ignoreUnknownKeys = true
        // classDiscriminator = "type"
    }) }
}

与 Gson 对比总结

对比项 Gson/Moshi Kotlinx.serialization
性能 ❌ 反射 ✅ 编译期生成,无反射
sealed class 多态支持 ❌ 复杂 ✅ 一行搞定
Kotlin default 值序列化 ❌ 不支持 ✅ 原生支持
包体积 ❌ 大 ✅ 小
跨平台(KMM) ❌ 不支持 ✅ KMM 友好

项目落地策略(迁移方案)

建议逐模块迁移:

新模块 → Kotlinx.serialization
旧模块 → 可混用 Gson,不强制一次性改完

迁移 checklist:

  • Model 加 @Serializable

  • Json 全局单例(避免频繁创建)

  • Retrofit/Ktor 换 converter

  • sealed class 都替换到多态序列化

下一篇:

Kotlinx.serialization 项目集成

相关推荐
数据知道2 小时前
PostgreSQL实战:详解如何用Python优雅地从PG中存取处理JSON
python·postgresql·json
游戏开发爱好者83 小时前
日常开发与测试的 App 测试方法、查看设备状态、实时日志、应用数据
android·ios·小程序·https·uni-app·iphone·webview
王码码20353 小时前
Flutter for OpenHarmony 实战之基础组件:第三十一篇 Chip 系列组件 — 灵活的标签化交互
android·flutter·交互·harmonyos
黑码哥3 小时前
ViewHolder设计模式深度剖析:iOS开发者掌握Android列表性能优化的实战指南
android·ios·性能优化·跨平台开发·viewholder
亓才孓3 小时前
[JDBC]元数据
android
独行soc4 小时前
2026年渗透测试面试题总结-17(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
金融RPA机器人丨实在智能4 小时前
Android Studio开发App项目进入AI深水区:实在智能Agent引领无代码交互革命
android·人工智能·ai·android studio
科技块儿4 小时前
利用IP查询在智慧城市交通信号系统中的应用探索
android·tcp/ip·智慧城市
独行soc4 小时前
2026年渗透测试面试题总结-18(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
王码码20355 小时前
Flutter for OpenHarmony 实战之基础组件:第二十七篇 BottomSheet — 动态底部弹窗与底部栏菜单
android·flutter·harmonyos