diff --git a/README.md b/README.md index 9d8f1b6..1991797 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ android { dependencies { // Gson 解析容错:https://github.com/getActivity/GsonFactory - implementation 'com.github.getActivity:GsonFactory:9.2' + implementation 'com.github.getActivity:GsonFactory:9.3' // Json 解析框架:https://github.com/google/gson implementation 'com.google.code.gson:gson:2.10.1' // Kotlin 反射库:用于反射 Kotlin data class 类对象 diff --git a/app/build.gradle b/app/build.gradle index 62d4b57..c09cb03 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,8 +8,8 @@ android { applicationId "com.hjq.gson.factory.demo" minSdkVersion 16 targetSdkVersion 31 - versionCode 920 - versionName "9.2" + versionCode 930 + versionName "9.3" testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } diff --git a/app/src/androidTest/java/com/hjq/gson/factory/test/DataClassBean.kt b/app/src/androidTest/java/com/hjq/gson/factory/test/DataClassBean.kt index 0872ace..b609220 100644 --- a/app/src/androidTest/java/com/hjq/gson/factory/test/DataClassBean.kt +++ b/app/src/androidTest/java/com/hjq/gson/factory/test/DataClassBean.kt @@ -1,8 +1,10 @@ package com.hjq.gson.factory.test data class DataClassBean( - val name: String?, - val age: Int = 18, - val address: String?, - val birthday: Long = System.currentTimeMillis() + val name: String = "轮子哥", + val alias: String, + val address: String? = "", + val age: Int = 20, + val weight: Int, + val stature: Int? = 180, ) \ No newline at end of file diff --git a/app/src/androidTest/java/com/hjq/gson/factory/test/JsonUnitTest.java b/app/src/androidTest/java/com/hjq/gson/factory/test/JsonUnitTest.java index c004d20..59983e5 100644 --- a/app/src/androidTest/java/com/hjq/gson/factory/test/JsonUnitTest.java +++ b/app/src/androidTest/java/com/hjq/gson/factory/test/JsonUnitTest.java @@ -44,12 +44,12 @@ public void onParseObjectException(TypeToken typeToken, String fieldName, Jso } @Override - public void onParseListException(TypeToken typeToken, String fieldName, JsonToken listItemJsonToken) { + public void onParseListItemException(TypeToken typeToken, String fieldName, JsonToken listItemJsonToken) { handlerGsonParseException("解析 List 异常:" + typeToken + "#" + fieldName + ",后台返回的条目类型为:" + listItemJsonToken); } @Override - public void onParseMapException(TypeToken typeToken, String fieldName, String mapItemKey, JsonToken mapItemJsonToken) { + public void onParseMapItemException(TypeToken typeToken, String fieldName, String mapItemKey, JsonToken mapItemJsonToken) { handlerGsonParseException("解析 Map 异常:" + typeToken + "#" + fieldName + ",mapItemKey = " + mapItemKey + ",后台返回的条目类型为:" + mapItemJsonToken); } diff --git a/library/build.gradle b/library/build.gradle index c5bc085..98f0cc0 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -6,8 +6,8 @@ android { defaultConfig { minSdkVersion 12 - versionCode 920 - versionName "9.2" + versionCode 930 + versionName "9.3" } // 使用 JDK 1.8 diff --git a/library/src/main/java/com/hjq/gson/factory/ParseExceptionCallback.java b/library/src/main/java/com/hjq/gson/factory/ParseExceptionCallback.java index 3981f5b..70af083 100644 --- a/library/src/main/java/com/hjq/gson/factory/ParseExceptionCallback.java +++ b/library/src/main/java/com/hjq/gson/factory/ParseExceptionCallback.java @@ -21,21 +21,21 @@ public interface ParseExceptionCallback { void onParseObjectException(TypeToken typeToken, String fieldName, JsonToken jsonToken); /** - * List 类型解析异常 + * List item 类型解析异常 * * @param typeToken 类型 Token * @param fieldName 字段名称(可能为空) * @param listItemJsonToken List 条目类型(可能为空) */ - void onParseListException(TypeToken typeToken, String fieldName, JsonToken listItemJsonToken); + void onParseListItemException(TypeToken typeToken, String fieldName, JsonToken listItemJsonToken); /** - * Map 类型解析异常 + * Map item 类型解析异常 * * @param typeToken 类型 Token * @param fieldName 字段名称(可能为空) * @param mapItemKey Map 集合中的 key 值,如果等于为 "null" 字符串,则证明后端返回了错误类型的 key 过来 * @param mapItemJsonToken Map 条目类型(可能为空) */ - void onParseMapException(TypeToken typeToken, String fieldName, String mapItemKey, JsonToken mapItemJsonToken); + void onParseMapItemException(TypeToken typeToken, String fieldName, String mapItemKey, JsonToken mapItemJsonToken); } \ No newline at end of file diff --git a/library/src/main/java/com/hjq/gson/factory/constructor/KotlinDataClassDefaultValueConstructor.kt b/library/src/main/java/com/hjq/gson/factory/constructor/KotlinDataClassDefaultValueConstructor.kt index cc0edd7..7451444 100644 --- a/library/src/main/java/com/hjq/gson/factory/constructor/KotlinDataClassDefaultValueConstructor.kt +++ b/library/src/main/java/com/hjq/gson/factory/constructor/KotlinDataClassDefaultValueConstructor.kt @@ -2,6 +2,7 @@ package com.hjq.gson.factory.constructor import com.google.gson.internal.ObjectConstructor import kotlin.reflect.KParameter +import kotlin.reflect.KType import kotlin.reflect.full.primaryConstructor import kotlin.reflect.jvm.isAccessible @@ -33,11 +34,24 @@ class KotlinDataClassDefaultValueConstructor(private val rawType: Class continue } - when { - // 判断这个参数是不是可选的 - constructor.parameters[i].isOptional -> fullInitialized = false - // 判断这个参数是否标记为空的 - constructor.parameters[i].type.isMarkedNullable -> values[i] = null + val parameter = constructor.parameters[i] + + // 判断这个参数是不是可选的 + if (parameter.isOptional) { + fullInitialized = false + } + + // 判断这个参数是否标记为空的 + if (parameter.type.isMarkedNullable) { + values[i] = null + } else if (!parameter.isOptional) { + // 如果这个参数没有标记为可空的,并且没有携带默认值 + // 就需要赋一个默认值给它,否则会实例化构造函数会出现崩溃 + // java.lang.IllegalArgumentException: method XxxBean. argument 3 has type int, got java.lang.Object + // 如果是基本数据类型就一定会出现崩溃,如果是对象的话,需要同时满足以下条件才会出现崩溃 + // 1. 后台给这个参数返回 null 的情况下 + // 2. 获取对象的时候,如果没有做判空,也会出现异常 + values[i] = getTypeDefaultValue(parameter.type) } } @@ -50,6 +64,30 @@ class KotlinDataClassDefaultValueConstructor(private val rawType: Class return result as T } + private fun getTypeDefaultValue(type: KType): Any? { + // "class kotlin.Int".endsWith("kotlin.Int") + if (String::class.toString().endsWith(type.toString())) { + return "" + } else if (Byte::class.toString().endsWith(type.toString())) { + return 0.toByte() + } else if (Short::class.toString().endsWith(type.toString())) { + return 0.toShort() + } else if (Int::class.toString().endsWith(type.toString())) { + return 0 + } else if (Long::class.toString().endsWith(type.toString())) { + return 0L + } else if (Float::class.toString().endsWith(type.toString())) { + return 0.0f + } else if (Double::class.toString().endsWith(type.toString())) { + return 0.0 + } else if (Char::class.toString().endsWith(type.toString())) { + return '\u0000' + } else if (Boolean::class.toString().endsWith(type.toString())) { + return false + } + return null + } + /** 一个简单的 Map,它使用参数索引而不是排序或哈希。 */ class IndexedParameterMap( private val parameterKeys: List, diff --git a/library/src/main/java/com/hjq/gson/factory/element/CollectionTypeAdapter.java b/library/src/main/java/com/hjq/gson/factory/element/CollectionTypeAdapter.java index 69b0f33..4c1d707 100644 --- a/library/src/main/java/com/hjq/gson/factory/element/CollectionTypeAdapter.java +++ b/library/src/main/java/com/hjq/gson/factory/element/CollectionTypeAdapter.java @@ -68,7 +68,7 @@ public Collection read(JsonReader in) throws IOException { e.printStackTrace(); ParseExceptionCallback callback = GsonFactory.getParseExceptionCallback(); if (callback != null) { - callback.onParseListException(mTypeToken, mFieldName, itemJsonToken); + callback.onParseListItemException(mTypeToken, mFieldName, itemJsonToken); } } } diff --git a/library/src/main/java/com/hjq/gson/factory/element/MapTypeAdapter.java b/library/src/main/java/com/hjq/gson/factory/element/MapTypeAdapter.java index 3b1a3fa..5e3d940 100644 --- a/library/src/main/java/com/hjq/gson/factory/element/MapTypeAdapter.java +++ b/library/src/main/java/com/hjq/gson/factory/element/MapTypeAdapter.java @@ -94,7 +94,7 @@ public Map read(JsonReader in) throws IOException { e.printStackTrace(); ParseExceptionCallback callback = GsonFactory.getParseExceptionCallback(); if (callback != null) { - callback.onParseMapException(mTypeToken, mFieldName, String.valueOf(key), itemJsonToken); + callback.onParseMapItemException(mTypeToken, mFieldName, String.valueOf(key), itemJsonToken); } } }