Kotlin中的序列化应用

Kotlin 序列化库 kotlinx.serialization 是一个强大的工具,可用于序列化和反序列化复杂的数据结构。

1,首先需要添加依赖

在模块级的build.gradle.kts(:app)中:

scss 复制代码
plugins {
    ......
	// 下面代码中version中代码中Kotlin的版本号
    kotlin("plugin.serialization") version "2.0.0"
}
dependencies {
	......
	implementation(libs.serialization.json)
	......
}

在libs.versions.toml文件中:

ini 复制代码
[versions]
serialization-json = "1.8.1"

[libraries]
serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "serialization-json"}

2,定义可序列化的数据结构

要确保数据结构的类被 @Serializable 注解标记。

kotlin 复制代码
import kotlinx.serialization.Serializable

@Serializable
data class Person(
    val name: String,
    val age: Int,
    val address: Address,
    val hobbies: List<String>
)

@Serializable
data class Address(
    val street: String,
    val city: String,
    val zipCode: String
)

3,序列化数据结构

借助 kotlinx.serialization.json.Json 类的 encodeToString 方法,能够将对象序列化为 JSON 字符串。

kotlin 复制代码
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json

fun main() {
    val address = Address("123 Main St", "Anytown", "12345")
    val person = Person("John Doe", 30, address, listOf("Reading", "Running"))

    val jsonString = Json.encodeToString(person)
    println("Serialized JSON: $jsonString")
}

4,反序列化数据结构

使用 kotlinx.serialization.json.Json 类的 decodeFromString 方法,可将 JSON 字符串反序列化为对象。

javascript 复制代码
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json

fun main() {
    val jsonString = """
        {
            "name": "John Doe",
            "age": 30,
            "address": {
                "street": "123 Main St",
                "city": "Anytown",
                "zipCode": "12345"
            },
            "hobbies": ["Reading", "Running"]
        }
    """.trimIndent()

    val person = Json.decodeFromString<Person>(jsonString)
    println("Deserialized Person: $person")
}

5, 处理嵌套集合等复杂情况

若数据结构包含嵌套集合,序列化和反序列化的过程是一样的。

kotlin 复制代码
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json

@Serializable
data class School(
    val name: String,
    val classes: List<ClassRoom>
)

@Serializable
data class ClassRoom(
    val grade: Int,
    val students: List<Student>
)

@Serializable
data class Student(
    val name: String,
    val age: Int
)

fun main() {
    val student1 = Student("Alice", 12)
    val student2 = Student("Bob", 13)
    val classRoom = ClassRoom(6, listOf(student1, student2))
    val school = School("ABC School", listOf(classRoom))

    val jsonString = Json.encodeToString(school)
    println("Serialized JSON: $jsonString")

    val deserializedSchool = Json.decodeFromString<School>(jsonString)
    println("Deserialized School: $deserializedSchool")
}

6,自定义序列化器

在某些情况下,默认的序列化器可能无法满足需求,这时可以自定义序列化器。

kotlin 复制代码
// 导入 kotlinx.serialization 库的所有基础类和注解,这些是实现序列化和反序列化功能的核心。
import kotlinx.serialization.*
// 用于表示基本数据类型的枚举类,在定义序列化描述符时会用到。
import kotlinx.serialization.descriptors.PrimitiveKind
// 用于创建基本数据类型的序列化描述符
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
// 序列化描述符的接口,描述了数据类型的结构,序列化和反序列化过程中会用到。
import kotlinx.serialization.descriptors.SerialDescriptor
// 用于从输入流中读取数据并将其转换为对象的接口,在反序列化时使用。
import kotlinx.serialization.encoding.Decoder
// 用于将对象转换为输出流的接口,在序列化时使用。
import kotlinx.serialization.encoding.Encoder
// 用于处理 JSON 格式的序列化和反序列化的类。
import kotlinx.serialization.json.Json

//@Serializable(with = CustomDateSerializer::class):
// 这是一个序列化注解,表明 Event 类是可序列化的。
// with 参数指定了使用自定义的序列化器 CustomDateSerializer 来处理 Event 类中的 date 字段。
@Serializable(with = CustomDateSerializer::class)
// 定义了一个名为 Event 的数据类,包含两个属性:name(字符串类型)和 date(java.util.Date 类型)。
data class Event(val name: String, val date: java.util.Date)

// 使用 object 关键字定义了一个单例对象 CustomDateSerializer,
// 它实现了 KSerializer<java.util.Date> 接口,用于处理 java.util.Date 类型的序列化和反序列化。
object CustomDateSerializer : KSerializer<java.util.Date> {
    // override val descriptor 重写了 KSerializer 接口中的 descriptor 属性, 用于描述序列化的数据类型。
    // 这里使用 PrimitiveSerialDescriptor 创建了一个描述符,表明 Date 类型将被序列化为一个长整型(PrimitiveKind.LONG)。
    override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Date", PrimitiveKind.LONG)

    // 重写了 KSerializer 接口中的 serialize 方法,用于将 java.util.Date 对象序列化为长整型。
    override fun serialize(encoder: Encoder, value: java.util.Date) {
        // 使用 Encoder 对象的 encodeLong 方法将 Date 对象的时间戳(通过 value.time 获取)写入输出流。
        encoder.encodeLong(value.time)
    }

    // 重写了 KSerializer 接口中的 deserialize 方法,用于从输入流中读取长整型数据并将其转换为 java.util.Date 对象。
    override fun deserialize(decoder: Decoder): java.util.Date {
        // 使用 Decoder 对象的 decodeLong 方法从输入流中读取长整型数据,然后将其作为参数传递给 java.util.Date 的构造函数,创建一个新的 Date 对象。
        return java.util.Date(decoder.decodeLong())
    }
}

fun main() {
    // 创建了一个 Event 对象,name 属性为 "Conference",date 属性为当前时间。
    val event = Event("Conference", java.util.Date())
    // 使用 Json 类的 encodeToString 方法将 Event 对象序列化为 JSON 字符串。
    val jsonString = Json.encodeToString(event)
    println("Serialized JSON: $jsonString")
    // 使用 Json 类的 decodeFromString 方法将 JSON 字符串反序列化为 Event 对象。
    val deserializedEvent = Json.decodeFromString<Event>(jsonString)
    println("Deserialized Event: $deserializedEvent")
}
相关推荐
Android-Flutter15 小时前
android compose LazyColumn 垂直列表滚动 使用
android·kotlin
儿歌八万首20 小时前
Jetpack Compose 自定义布局解析
kotlin·compose·自定义布局
Kapaseker20 小时前
初级与中级的Android面试题区别在哪里
android·kotlin
zFox21 小时前
二、Kotlin高级特性以及Compose状态驱动UI
ui·kotlin·compose
PuddingSama1 天前
Gson 很好,但在Kotlin上有更合适的序列化工具「Kotlin Serialization」
android·kotlin·gson
郑梓斌2 天前
Luban 2:简洁高效的Android图片压缩库
微信·kotlin
我命由我123452 天前
Android Jetpack Compose - Compose 重组、AlertDialog、LazyColumn、Column 与 Row
android·java·java-ee·kotlin·android studio·android jetpack·android-studio
愤怒的代码2 天前
在 Android 中执行 View.invalidate() 方法后经历了什么
android·java·kotlin
Android-Flutter2 天前
android compose PullToRefreshAndLoadMore 下拉刷新 + 上拉加载更多 使用
android·kotlin