KMP 结构适配鸿蒙:JSON 序列化与反序列化
本文介绍了如何在KMP项目中实现跨平台JSON序列化,重点讲解了Kotlin官方序列化库的使用方法。文章首先阐述了JSON序列化的核心概念,包括数据模型定义和序列化管理器的实现。随后详细说明了Android、JVM(鸿蒙)等平台的特定实现方式,以及编译后的JavaScript代码形式。此外还展示了鸿蒙系统中的实际应用案例,并介绍了处理复杂JSON结构和自定义序列化器的高级功能。通过注解和类型安全的
项目概述
JSON 是现代应用开发中最常用的数据交换格式。无论是与服务器通信、保存配置文件,还是在应用内部传递数据,JSON 都无处不在。Kotlin 提供了官方的序列化库,使得 JSON 处理变得更加简洁和类型安全。本文将详细介绍如何在 KMP 项目中实现跨平台的 JSON 序列化和反序列化。
第一部分:JSON 序列化的核心概念
理解序列化的重要性
序列化是将对象转换为可以存储或传输的格式的过程。反序列化是反向过程,将格式化的数据转换回对象。在应用开发中,我们经常需要将对象转换为 JSON 字符串发送给服务器,或者从服务器接收 JSON 字符串并转换为对象。
Kotlin 序列化库提供了一个类型安全的方式来处理 JSON,避免了手动编写序列化代码的复杂性。通过使用注解,我们可以轻松地将任何数据类转换为 JSON。
定义可序列化的数据模型
首先,我们定义一些可序列化的数据模型。
// commonMain/kotlin/com/example/kmp/serialization/Models.kt
import kotlinx.serialization.Serializable
@Serializable
data class User(
val id: String,
val name: String,
val email: String,
val age: Int
)
@Serializable
data class Post(
val id: String,
val title: String,
val content: String,
val author: User,
val tags: List<String> = emptyList()
)
@Serializable
data class ApiResponse<T>(
val code: Int,
val message: String,
val data: T?
)
使用 @Serializable 注解,编译器会自动为这些类生成序列化代码。
实现序列化管理器
接下来,我们创建一个序列化管理器。
// commonMain/kotlin/com/example/kmp/serialization/JsonSerializer.kt
import kotlinx.serialization.json.Json
import kotlinx.serialization.encodeToString
import kotlinx.serialization.decodeFromString
object JsonSerializer {
private val json = Json {
ignoreUnknownKeys = true
prettyPrint = false
}
inline fun <reified T> toJson(obj: T): String {
return json.encodeToString(obj)
}
inline fun <reified T> fromJson(jsonString: String): T? {
return try {
json.decodeFromString(jsonString)
} catch (e: Exception) {
null
}
}
}
这个管理器提供了简洁的 JSON 序列化和反序列化接口。
第二部分:平台特定的序列化实现
Android 平台的序列化
在 Android 平台上,我们可以直接使用 Kotlin 序列化库。Android 的 JSON 处理相对简单,因为 Kotlin 序列化库已经完全支持。我们只需要配置 Json 对象的选项,如是否忽略未知字段、是否格式化输出等。
// androidMain/kotlin/com/example/kmp/serialization/AndroidJsonSerializer.kt
actual object PlatformJsonSerializer {
actual fun <T> serialize(obj: T, serializer: KSerializer<T>): String {
return Json.encodeToString(serializer, obj)
}
actual fun <T> deserialize(json: String, serializer: KSerializer<T>): T? {
return try {
Json.decodeFromString(serializer, json)
} catch (e: Exception) {
null
}
}
}
JVM 平台的序列化(鸿蒙)
在鸿蒙系统上,我们同样使用 Kotlin 序列化库。
// jvmMain/kotlin/com/example/kmp/serialization/JvmJsonSerializer.kt
actual object PlatformJsonSerializer {
actual fun <T> serialize(obj: T, serializer: KSerializer<T>): String {
return Json.encodeToString(serializer, obj)
}
actual fun <T> deserialize(json: String, serializer: KSerializer<T>): T? {
return try {
Json.decodeFromString(serializer, json)
} catch (e: Exception) {
null
}
}
}
第三部分:编译后的代码形式
Kotlin 序列化代码编译为 JavaScript
当我们将 Kotlin 的序列化代码编译为 JavaScript 时,会生成以下形式的代码:
// 编译后的 JavaScript (简化版)
var JsonSerializer = {
toJson: function(obj) {
return JSON.stringify(obj);
},
fromJson: function(jsonString) {
try {
return JSON.parse(jsonString);
} catch (e) {
return null;
}
}
};
Web 平台的序列化
在 Web 平台上,我们可以使用浏览器的原生 JSON API。
// Web 平台的序列化
var WebJsonSerializer = {
toJson: function(obj) {
return JSON.stringify(obj);
},
fromJson: function(jsonString) {
try {
return JSON.parse(jsonString);
} catch (e) {
console.error("JSON parse error:", e);
return null;
}
}
};
第四部分:鸿蒙系统中的实际应用
在鸿蒙应用中使用 JSON 序列化
在鸿蒙应用中,我们可以直接使用编译后的 KMP 序列化代码。
// HarmonyOS 应用代码
class HarmonyUserService {
fun saveUser(user: User) {
val json = JsonSerializer.toJson(user)
// 保存到文件或数据库
}
fun loadUser(json: String): User? {
return JsonSerializer.fromJson(json)
}
}
处理复杂的 JSON 结构
在实际应用中,我们经常需要处理复杂的 JSON 结构。
// 处理复杂 JSON
@Serializable
data class ComplexData(
val users: List<User>,
val posts: List<Post>,
val metadata: Map<String, String>
)
val complexJson = """
{
"users": [...],
"posts": [...],
"metadata": {...}
}
"""
val data = JsonSerializer.fromJson<ComplexData>(complexJson)
第五部分:高级序列化功能
实现自定义序列化器
有时候,我们需要自定义序列化行为。例如,当处理特殊的数据类型(如 DateTime)时,我们需要定义如何将其转换为 JSON 字符串,以及如何从 JSON 字符串恢复它。通过实现 KSerializer 接口,我们可以完全控制序列化和反序列化的过程。
// 自定义序列化器
object DateTimeSerializer : KSerializer<DateTime> {
override val descriptor: SerialDescriptor =
PrimitiveSerialDescriptor("DateTime", PrimitiveKind.STRING)
override fun serialize(encoder: Encoder, value: DateTime) {
encoder.encodeString(value.toString())
}
override fun deserialize(decoder: Decoder): DateTime {
return DateTime.parse(decoder.decodeString())
}
}

这个流程图展示了完整的序列化和反序列化过程,包括对象到 JSON 的转换、JSON 到对象的恢复,以及自定义序列化器的使用。
总结
通过本文的学习,我们理解了如何在 KMP 项目中实现跨平台的 JSON 序列化和反序列化。Kotlin 序列化库提供了一个类型安全和高效的方式来处理 JSON 数据。通过使用注解和泛型,我们可以轻松地将任何数据类转换为 JSON,或从 JSON 转换回数据类。
更多推荐



所有评论(0)