Kotlin serialization consists of a compiler plugin, that generates visitor code for serializable classes, runtime library with core serialization API and JSON format, and support libraries with
ProtoBuf, CBOR and properties formats.
Kotlin官方的序列化库,具有以下特点:
@serializable
编译器生成序列化代码从而避免反射JSON
,CBOR
, Protobuf
等多种格式Kotlinx.serialization
支持的格式很多,0.2.0开始增加了对HOCON
的支持:https://github.com/Kotlin/kotlinx.serialization/blob/master/formats/README.md
Android开发中经常用到Gson
、Jackson
、Moshi
、kotshi
等Json解析库,全面转向Kotlin开发后,kotlinx.serialization
也是一个很好的选择。
root的build.gradle
buildscript {
ext.kotlin_version = "1.3.70" // 最低v1.3.30以上
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
}
}
module的build.gradle
repositories {
jcenter()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" // or "kotlin-stdlib-jdk8"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.20.0"
}
也可用kts进行gradle配置,如下:
plugins {
kotlin("multiplatform") // or kotlin("jvm") or any other kotlin plugin
kotlin("plugin.serialization") version "1.3.70"
}
repositories {
// artifacts are published to JCenter
jcenter()
}
dependencies {
implementation(kotlin("stdlib", KotlinCompilerVersion.VERSION)) // or "stdlib-jdk8"
implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.20.0") // JVM dependency
}
proguard-rules.pro
-keepattributes *Annotation*, InnerClasses
-dontnote kotlinx.serialization.SerializationKt
-keep,includedescriptorclasses class com.yourcompany.yourpackage.**$$serializer { *; } # <-- change package name to your app's
-keepclassmembers class com.yourcompany.yourpackage.** { # <-- change package name to your app's
*** Companion;
}
-keepclasseswithmembers class com.yourcompany.yourpackage.** { # <-- change package name to your app's
kotlinx.serialization.KSerializer serializer(...);
}
如上,就可以在工程中使用kotlinx.serialzation
了。
接下实现Json解析的代码
import kotlinx.serialization.*
import kotlinx.serialization.json.*
@Serializable // 1
data class Data(
val id: Int,
@SerialName("user_name") // 2
val name: String = "hoge",
@SerialName("mail_address")
val mailAddress: String? = "" // 3
)
@Serializable
@SerialName
可以重新定义序列化时的参数名除了以上几个常用注解外,还有@Required
等其他注解满足序列化过程的其他需求
// sample data
val json = """{"id":0,"user_name":"hoge","mail_address":"[email protected]"}"""
val obj = Json(JsonConfiguration.Stable).parse(Data.serializer(), json)
Json(....)
中进行序列化的设置,JsonConfiguration.Stable
是缺省设置,可以不显式指定,其定义如下:
companion object {
@JvmStatic
public val Stable = JsonConfiguration(
encodeDefaults = true,
ignoreUnknownKeys = false,
isLenient = false,
serializeSpecialFloatingPointValues = false,
allowStructuredMapKeys = true,
prettyPrint = false,
unquotedPrint = false,
indent = defaultIndent,
useArrayPolymorphism = false,
classDiscriminator = defaultDiscriminator
)
}
可以通过查看源码了解上面各项目的具体函数以。
Stable
的检查比较严格, 如果mail_address
不是可空类型,但在解析时数据为空,使用Stable
可以在parse时抛出error,避免运行时的NPE。Moshi也提供类似功能,处理Kotlin的空安全( Moshi兼容Kotlin空安全)
当然,也可以自定义JsonConfiguration
的内容,例如
// sample data
val json = """{"id":0,"user_name":"hoge"}"""
val parsedJson = Json(
JsonConfiguration(
isLenient = true, // 1
ignoreUnknownKeys = true,
serializeSpecialFloatingPointValues = true
)
).parse(Data.serializer(), json)
上面的配置就不会在在解析时,因为遇到非法Null值而抛出异常,但同时将风险留到了后面。
0.14.0起可以通过下面的方法处理可空的value,更加方便了
// sample data
val json = """{"id":0,"name":"hoge"}"""
val obj = Json.nonstrict.parse(Data.serializer(), json)
最后比较一下Moshi
和Kotlinx.serialization
,这两个库都是适合在Kotlin使用的序列化库