From 18fb29b5a4c9a845d9a740dc7d6adb0ebf628525 Mon Sep 17 00:00:00 2001 From: XXF Date: Tue, 26 Dec 2023 12:25:51 +0800 Subject: [PATCH] =?UTF-8?q?feat:1.4.0=20=E6=AD=A3=E5=BC=8F=E7=89=88=20?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E7=BB=A7=E6=89=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 230 +++++++++--------- demo/build.gradle | 4 +- .../json/gson/booster/kaptdemo/extend/User.kt | 19 ++ pkdemo/build.gradle | 4 +- 4 files changed, 140 insertions(+), 117 deletions(-) create mode 100644 demo/src/main/java/com/xxf/json/gson/booster/kaptdemo/extend/User.kt diff --git a/README.md b/README.md index 291d9fc..d13b1f1 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Table of Contents * [KAPT\-support](#kapt-support) * [用法](#用法) * [KSP\-Support](#ksp-support) -* [已知问题](#已知问题) +* [已知问题](#常见问题) # gson_plugin gson_plugin是一个注解处理器,能够在编译期自动生成**兼容Kotlin特性的**、**高性能TypeAdapter**,以提升Gson的序列化与反序列化时间性能。同时也解决了kotlin默认值的问题.平均**比原始Gson快10倍**。 ## 主要方向 @@ -47,69 +47,69 @@ gson_plugin是一个注解处理器,能够在编译期自动生成**兼容Kotl # 注解解释 ```kotlin annotation class JsonModel( - /** - * 控制该模型节点里面 是否是空安全 默认true - * - * 如,对于int类型的声明 - * 如果是val i:Int? 将不受任何影响 - * 如果是val i:Int json里面是null 那么设置为false 将会报错,否则将会跳过这个字段 - * - * 受影响范围 [INT, LONG, FLOAT, DOUBLE, STRING, BOOLEAN,ENUM] - */ - val nullSafe: Boolean = true, - /** - * 控制该模型节点里面 是否强类型匹配 默认false - * - * 如,对于int类型的声明 - *如果是val i:Int? 将不受任何影响 - * 如果是val i:Int json里面是"" 那么设置为true 将会报错,否则继续调用gson.getAdapter 继续责任链解析(交给gson自带的或者registerTypeAdapter等来解析) - * - * 受影响范围 [INT, LONG, FLOAT, DOUBLE, STRING, BOOLEAN,ENUM] - */ - val strictType: Boolean = false, - - /** - * 生成的adapter文件 后缀名字 默认“AutoGeneratedTypeAdapter” - */ - val adapterNameSuffix: String = "AutoGeneratedTypeAdapter", - - /** - * 序列化最终数据类型 默认 SerializedType.STRING - * Gson对于枚举默认序列化成String类型 - * - * 受影响范围[ ENUM_CLASS ] - */ - val serializedType: SerializedType = SerializedType.STRING, - - /** - * 反序列化的默认值, - * 如果枚举没有声明成可空类型,那么运行时将会导致bug,还有服务器可能增加枚举,那么老版本的app将会解析为null - * 比如 - * @JsonModel(deserializedDefaultValue="undefined") - * enum class Enum1 { - * @SerializedName("undefined") - * UNDEFINED, - * @SerializedName("x") - * A, - * @SerializedName("2") - * B - * } - * 那么 默认值 可以是 “undefined" 或者 ”UNDEFINED" - * - * 受影响范围[ ENUM_CLASS ] - */ - val deserializedDefaultValue: String = "", - - /** - * 控制该模型节点里面 是否序列化null 默认SerializeNulls.INHERIT - * api 于 gson.serializeNulls 或者 JsonWriter.serializeNulls - * - * 默认继承上游jsonWriter的控制(等价于gson的设置,除非中间层有拦截) - * 此类完成之后 会恢复继承性,不会影响其他节点! - * - * 场景:常用于后端 置空逻辑,需要前端传递其null值 - */ - val serializeNulls: SerializeNulls = SerializeNulls.INHERIT + /** + * 控制该模型节点里面 是否是空安全 默认true + * + * 如,对于int类型的声明 + * 如果是val i:Int? 将不受任何影响 + * 如果是val i:Int json里面是null 那么设置为false 将会报错,否则将会跳过这个字段 + * + * 受影响范围 [INT, LONG, FLOAT, DOUBLE, STRING, BOOLEAN,ENUM] + */ + val nullSafe: Boolean = true, + /** + * 控制该模型节点里面 是否强类型匹配 默认false + * + * 如,对于int类型的声明 + *如果是val i:Int? 将不受任何影响 + * 如果是val i:Int json里面是"" 那么设置为true 将会报错,否则继续调用gson.getAdapter 继续责任链解析(交给gson自带的或者registerTypeAdapter等来解析) + * + * 受影响范围 [INT, LONG, FLOAT, DOUBLE, STRING, BOOLEAN,ENUM] + */ + val strictType: Boolean = false, + + /** + * 生成的adapter文件 后缀名字 默认“AutoGeneratedTypeAdapter” + */ + val adapterNameSuffix: String = "AutoGeneratedTypeAdapter", + + /** + * 序列化最终数据类型 默认 SerializedType.STRING + * Gson对于枚举默认序列化成String类型 + * + * 受影响范围[ ENUM_CLASS ] + */ + val serializedType: SerializedType = SerializedType.STRING, + + /** + * 反序列化的默认值, + * 如果枚举没有声明成可空类型,那么运行时将会导致bug,还有服务器可能增加枚举,那么老版本的app将会解析为null + * 比如 + * @JsonModel(deserializedDefaultValue="undefined") + * enum class Enum1 { + * @SerializedName("undefined") + * UNDEFINED, + * @SerializedName("x") + * A, + * @SerializedName("2") + * B + * } + * 那么 默认值 可以是 “undefined" 或者 ”UNDEFINED" + * + * 受影响范围[ ENUM_CLASS ] + */ + val deserializedDefaultValue: String = "", + + /** + * 控制该模型节点里面 是否序列化null 默认SerializeNulls.INHERIT + * api 于 gson.serializeNulls 或者 JsonWriter.serializeNulls + * + * 默认继承上游jsonWriter的控制(等价于gson的设置,除非中间层有拦截) + * 此类完成之后 会恢复继承性,不会影响其他节点! + * + * 场景:常用于后端 置空逻辑,需要前端传递其null值 + */ + val serializeNulls: SerializeNulls = SerializeNulls.INHERIT ) @@ -117,31 +117,31 @@ annotation class JsonModel( * 配合注解[com.xxf.json.gson.booster.annotation.JsonModel] 用于控制自动生成的Adapter逻辑 */ annotation class JsonField( - /** - * 是否归属自动生成的TypeAdapter - * 否则将会用gson自带的adapter来解析 - */ - val attached: Boolean = true, - /** - * 是否是空安全 默认true - * - * 如,对于int类型的声明 - * 如果是val i:Int? 将不受任何影响 - * 如果是val i:Int json里面是null 那么设置为false 将会报错,否则将会跳过这个字段 - * - * 受影响范围 [INT, LONG, FLOAT, DOUBLE, STRING, BOOLEAN,ENUM] - */ - val nullSafe: Boolean = true, - /** - * 是否强类型匹配 默认false - * - * 如,对于int类型的声明 - * 如果是val i:Int? 将不受任何影响 - * 如果是val i:Int json里面是"" 那么设置为true 将会报错,否则继续调用gson.getAdapter 继续责任链解析(交给gson自带的或者registerTypeAdapter等来解析) - * - * 受影响范围 [INT, LONG, FLOAT, DOUBLE, STRING, BOOLEAN,ENUM] - */ - val strictType: Boolean = false + /** + * 是否归属自动生成的TypeAdapter + * 否则将会用gson自带的adapter来解析 + */ + val attached: Boolean = true, + /** + * 是否是空安全 默认true + * + * 如,对于int类型的声明 + * 如果是val i:Int? 将不受任何影响 + * 如果是val i:Int json里面是null 那么设置为false 将会报错,否则将会跳过这个字段 + * + * 受影响范围 [INT, LONG, FLOAT, DOUBLE, STRING, BOOLEAN,ENUM] + */ + val nullSafe: Boolean = true, + /** + * 是否强类型匹配 默认false + * + * 如,对于int类型的声明 + * 如果是val i:Int? 将不受任何影响 + * 如果是val i:Int json里面是"" 那么设置为true 将会报错,否则继续调用gson.getAdapter 继续责任链解析(交给gson自带的或者registerTypeAdapter等来解析) + * + * 受影响范围 [INT, LONG, FLOAT, DOUBLE, STRING, BOOLEAN,ENUM] + */ + val strictType: Boolean = false ) ``` # 仓库权限 @@ -185,8 +185,8 @@ plugins { } dependencies { - implementation("com.NBXXF.gson_plugin:lib_gson_annotation:1.3.0-SNAPSHOT") - kapt("com.NBXXF.gson_plugin:lib_gson_plugin_kapt:1.3.0-SNAPSHOT") + implementation("com.NBXXF.gson_plugin:lib_gson_annotation:1.4.0") + kapt("com.NBXXF.gson_plugin:lib_gson_plugin_kapt:1.4.0") } kapt { @@ -207,8 +207,8 @@ plugins { } dependencies { - implementation("com.NBXXF.gson_plugin:lib_gson_annotation:1.3.0-SNAPSHOT") - kapt("com.NBXXF.gson_plugin:lib_gson_plugin_kapt:1.3.0-SNAPSHOT") + implementation("com.NBXXF.gson_plugin:lib_gson_annotation:1.4.0") + kapt("com.NBXXF.gson_plugin:lib_gson_plugin_kapt:1.4.0") } kapt { @@ -278,8 +278,8 @@ android { } dependencies { - implementation('com.NBXXF.gson_plugin:lib_gson_annotation:1.3.0-SNAPSHOT') - ksp('com.NBXXF.gson_plugin:lib_gson_plugin_ksp:1.3.0-SNAPSHOT') + implementation('com.NBXXF.gson_plugin:lib_gson_annotation:1.4.0') + ksp('com.NBXXF.gson_plugin:lib_gson_plugin_ksp:1.4.0') } ksp { @@ -306,37 +306,41 @@ app模块build.gradle ```kotlin plugins { - id("com.google.devtools.ksp") + id("com.google.devtools.ksp") } android { - // KSP生成的代码不能被IDE自动识别到,需要手动添加到sourceSets中 - buildTypes { - getByName("debug") { - sourceSets.getByName("main") { - java.srcDir("build/generated/ksp/debug/kotlin") - } - } - getByName("release") { - sourceSets.getByName("main") { - java.srcDir("build/generated/ksp/release/kotlin") - } - } + // KSP生成的代码不能被IDE自动识别到,需要手动添加到sourceSets中 + buildTypes { + getByName("debug") { + sourceSets.getByName("main") { + java.srcDir("build/generated/ksp/debug/kotlin") + } + } + getByName("release") { + sourceSets.getByName("main") { + java.srcDir("build/generated/ksp/release/kotlin") + } } + } } dependencies { - implementation('com.NBXXF.gson_plugin:lib_gson_annotation:1.3.0-SNAPSHOT') - ksp('com.NBXXF.gson_plugin:lib_gson_plugin_ksp:1.3.0-SNAPSHOT') + implementation('com.NBXXF.gson_plugin:lib_gson_annotation:1.4.0') + ksp('com.NBXXF.gson_plugin:lib_gson_plugin_ksp:1.4.0') } ksp { - // 指定生成TypeAdapterFactory的全限定名,不指定则不生成 - arg("factory", "com.xxf.json.gson.plugin.AutoTypeAdapterFactory") + // 指定生成TypeAdapterFactory的全限定名,不指定则不生成 + arg("factory", "com.xxf.json.gson.plugin.AutoTypeAdapterFactory") } ``` -# 已知问题 +# 常见问题 1. final/val 属性不能声明在body中(由于不是反射,要么就舍弃了,现在还是框架不让这么写,欢迎写成var) 2. 继承模型,父类属性不能包含final/val 修饰 (由于不是反射,要么就舍弃了,现在还是框架不让这么写,欢迎写成var) +3. 父类添加了@JsonModel 子类如果不添加 那么就用的gson的反射解析,建议子类也要一并添加注解,原理还是声明式,没有反射的灵活 +4. 如果自定义Adapter 但是又不想全部放弃自动生成的Adapter 比如自定义的BoolTypeAdapter 那么只需要 在AutoTypeAdapterFactory 之前注册到对应的Gson +5. 如果类里面 某个字段不想参与自动生成,那么只需要@JsonField(attached=false) 或者 @JsonAdapter(xxxClass) 那么就能解耦 +6. 如何对基本类型进行类型兼容,比如对Int类型 服务器的双引号需要解析成0,只需要在gson上注册GsonTypeAdapterFactory,两者可共存,请参考[xxf_android:lib_json](https://github.com/NBXXF/xxf_android/blob/master/lib_json/src/main/java/com/xxf/json/typeadapterfactory/SafeTypeAdapterFactory.java) diff --git a/demo/build.gradle b/demo/build.gradle index a9f3484..349a312 100644 --- a/demo/build.gradle +++ b/demo/build.gradle @@ -63,8 +63,8 @@ dependencies { api "io.reactivex.rxjava2:rxandroid:2.1.1" api "io.reactivex.rxjava2:rxkotlin:2.4.0" - implementation 'com.NBXXF.gson_plugin:lib_gson_annotation:1.3.0-SNAPSHOT' - kapt "com.NBXXF.gson_plugin:lib_gson_plugin_kapt:1.3.0-SNAPSHOT" + implementation 'com.NBXXF.gson_plugin:lib_gson_annotation:1.4.0' + kapt "com.NBXXF.gson_plugin:lib_gson_plugin_kapt:1.4.0" } diff --git a/demo/src/main/java/com/xxf/json/gson/booster/kaptdemo/extend/User.kt b/demo/src/main/java/com/xxf/json/gson/booster/kaptdemo/extend/User.kt new file mode 100644 index 0000000..f05b0d3 --- /dev/null +++ b/demo/src/main/java/com/xxf/json/gson/booster/kaptdemo/extend/User.kt @@ -0,0 +1,19 @@ +package com.xxf.json.gson.booster.kaptdemo.extend + +import com.xxf.json.gson.booster.annotation.JsonModel + +@JsonModel +open class Parent( + open var name1: String="", + var age: Int=1 +) { + +} + +@JsonModel +class WChild( + override var name1: String = "", + age2: Int = 1, +):Parent(name1,age2) { + var des: String = ""; +} diff --git a/pkdemo/build.gradle b/pkdemo/build.gradle index 7b9d2b5..67eb947 100644 --- a/pkdemo/build.gradle +++ b/pkdemo/build.gradle @@ -64,8 +64,8 @@ dependencies { api "io.reactivex.rxjava2:rxandroid:2.1.1" api "io.reactivex.rxjava2:rxkotlin:2.4.0" - implementation 'com.NBXXF.gson_plugin:lib_gson_annotation:1.3.0-SNAPSHOT' - kapt "com.NBXXF.gson_plugin:lib_gson_plugin_kapt:1.3.0-SNAPSHOT" + implementation 'com.NBXXF.gson_plugin:lib_gson_annotation:1.4.0' + kapt "com.NBXXF.gson_plugin:lib_gson_plugin_kapt:1.4.0" // implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0"))