GithubHelp home page GithubHelp logo

getactivity / gsonfactory Goto Github PK

View Code? Open in Web Editor NEW
664.0 664.0 64.0 659 KB

Gson 解析容错框架,愿从此再无 Json 解析报错

License: Apache License 2.0

Java 94.72% Kotlin 5.28%
android gson gson-adapter gson-converter gsonadapter java okhttp retrofit2 rxjava

gsonfactory's Introduction

我是一名热爱 Android 技术的程序员,平时爱造轮子,人送外号轮子哥

我的理想是让这个世界没有难开发的安卓项目,消灭一切难维护的代码。

gsonfactory's People

Contributors

880634 avatar getactivity avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

gsonfactory's Issues

[疑惑]:为啥fastjson解析的是正常的,本框架解析的不一样

问题描述【必填】

比如字段 attitude、collectTime

image
image
image
image
image

框架文档是否提及了该问题【必答】

是否已经查阅框架文档但还未能解决的【必答】

issue 列表中是否有人曾提过类似的问题【必答】

是否已经搜索过了 issue 列表但还未能解决的【必答】

[Bug]:解析出现报错

框架版本【必填】

9.5

问题描述【必填】

  • 我使用 com.github.getActivity:EasyHttp:12.8 框架,代码拷贝的是 EasyHttp 的模板代码,使用 com.github.getActivity:GsonFactory:9.5 解析的时候会报错,错误信息
No virtual method getModule()Ljava/lang/Module; in class Ljava/lang/Class; or its super classes (declaration of 'java.lang.Class' appears in /apex/com.android.art/javalib/core-oj.jar)
java.lang.NoSuchMethodError: No virtual method getModule()Ljava/lang/Module; in class Ljava/lang/Class; or its super classes (declaration of 'java.lang.Class' appears in /apex/com.android.art/javalib/core-oj.jar)
	at kotlin.reflect.jvm.internal.impl.serialization.deserialization.builtins.BuiltInsResourceLoader.loadResource(BuiltInsResourceLoader.java:26)
	at kotlin.reflect.jvm.internal.impl.descriptors.runtime.components.ReflectKotlinClassFinder.findBuiltInsData(ReflectKotlinClassFinder.kt:52)
	at kotlin.reflect.jvm.internal.impl.builtins.jvm.JvmBuiltInsPackageFragmentProvider.findPackage(JvmBuiltInsPackageFragmentProvider.kt:60)
	at kotlin.reflect.jvm.internal.impl.serialization.deserialization.AbstractDeserializedPackageFragmentProvider$fragments$1.invoke(AbstractDeserializedPackageFragmentProvider.kt:35)
	at kotlin.reflect.jvm.internal.impl.serialization.deserialization.AbstractDeserializedPackageFragmentProvider$fragments$1.invoke(AbstractDeserializedPackageFragmentProvider.kt:34)
	at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$MapBasedMemoizedFunction.invoke(LockBasedStorageManager.java:578)
	at kotlin.reflect.jvm.internal.impl.serialization.deserialization.AbstractDeserializedPackageFragmentProvider.collectPackageFragments(AbstractDeserializedPackageFragmentProvider.kt:43)
	at kotlin.reflect.jvm.internal.impl.descriptors.PackageFragmentProviderKt.collectPackageFragmentsOptimizedIfPossible(PackageFragmentProvider.kt:50)
	at kotlin.reflect.jvm.internal.impl.descriptors.impl.CompositePackageFragmentProvider.collectPackageFragments(CompositePackageFragmentProvider.kt:47)
	at kotlin.reflect.jvm.internal.impl.descriptors.PackageFragmentProviderKt.collectPackageFragmentsOptimizedIfPossible(PackageFragmentProvider.kt:50)
	at kotlin.reflect.jvm.internal.impl.descriptors.impl.CompositePackageFragmentProvider.collectPackageFragments(CompositePackageFragmentProvider.kt:47)
	at kotlin.reflect.jvm.internal.impl.descriptors.PackageFragmentProviderKt.collectPackageFragmentsOptimizedIfPossible(PackageFragmentProvider.kt:50)
	at kotlin.reflect.jvm.internal.impl.descriptors.PackageFragmentProviderKt.packageFragments(PackageFragmentProvider.kt:41)
	at kotlin.reflect.jvm.internal.impl.descriptors.impl.LazyPackageViewDescriptorImpl$fragments$2.invoke(LazyPackageViewDescriptorImpl.kt:38)
	at kotlin.reflect.jvm.internal.impl.descriptors.impl.LazyPackageViewDescriptorImpl$fragments$2.invoke(LazyPackageViewDescriptorImpl.kt:37)
	at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:408)
	at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedNotNullLazyValue.invoke(LockBasedStorageManager.java:527)
	at kotlin.reflect.jvm.internal.impl.storage.StorageKt.getValue(storage.kt:42)
	at kotlin.reflect.jvm.internal.impl.descriptors.impl.LazyPackageViewDescriptorImpl.getFragments(LazyPackageViewDescriptorImpl.kt:37)
	at kotlin.reflect.jvm.internal.impl.descriptors.impl.LazyPackageViewDescriptorImpl$memberScope$1.invoke(LazyPackageViewDescriptorImpl.kt:42)
	at kotlin.reflect.jvm.internal.impl.descriptors.impl.LazyPackageViewDescriptorImpl$memberScope$1.invoke(LazyPackageViewDescriptorImpl.kt:41)
	at kotlin.reflect.jvm.internal.impl.resolve.scopes.LazyScopeAdapter$lazyScope$1.invoke(LazyScopeAdapter.kt:28)
	at kotlin.reflect.jvm.internal.impl.resolve.scopes.LazyScopeAdapter$lazyScope$1.invoke(LazyScopeAdapter.kt:27)
	at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:408)
	at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedNotNullLazyValue.invoke(LockBasedStorageManager.java:527)
2024-01-23 10:33:42.733 19935-19991 EasyHttp D...pi@c16eb70 cn.smart.hospital                    E  	at kotlin.reflect.jvm.internal.impl.resolve.scopes.LazyScopeAdapter.getWorkerScope(LazyScopeAdapter.kt:34)
	at kotlin.reflect.jvm.internal.impl.resolve.scopes.AbstractScopeAdapter.getContributedClassifier(AbstractScopeAdapter.kt:44)
	at kotlin.reflect.jvm.internal.impl.builtins.KotlinBuiltIns$3.invoke(KotlinBuiltIns.java:91)
	at kotlin.reflect.jvm.internal.impl.builtins.KotlinBuiltIns$3.invoke(KotlinBuiltIns.java:88)
	at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$MapBasedMemoizedFunction.invoke(LockBasedStorageManager.java:578)
	at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$MapBasedMemoizedFunctionToNotNull.invoke(LockBasedStorageManager.java:651)
	at kotlin.reflect.jvm.internal.impl.builtins.KotlinBuiltIns.getBuiltInClassByName(KotlinBuiltIns.java:223)
	at kotlin.reflect.jvm.internal.impl.builtins.KotlinBuiltIns.getAny(KotlinBuiltIns.java:228)
	at kotlin.reflect.jvm.internal.impl.builtins.KotlinBuiltIns.getAnyType(KotlinBuiltIns.java:498)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaTypeParameterDescriptor.computeNotEnhancedBounds(LazyJavaTypeParameterDescriptor.kt:56)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaTypeParameterDescriptor.resolveUpperBounds(LazyJavaTypeParameterDescriptor.kt:48)
	at kotlin.reflect.jvm.internal.impl.descriptors.impl.AbstractTypeParameterDescriptor$TypeParameterTypeConstructor.computeSupertypes(AbstractTypeParameterDescriptor.java:168)
	at kotlin.reflect.jvm.internal.impl.types.AbstractTypeConstructor$supertypes$1.invoke(AbstractTypeConstructor.kt:83)
	at kotlin.reflect.jvm.internal.impl.types.AbstractTypeConstructor$supertypes$1.invoke(AbstractTypeConstructor.kt:83)
	at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:408)
	at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedLazyValueWithPostCompute.invoke(LockBasedStorageManager.java:481)
	at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedNotNullLazyValueWithPostCompute.invoke(LockBasedStorageManager.java:512)
	at kotlin.reflect.jvm.internal.impl.types.AbstractTypeConstructor.getSupertypes(AbstractTypeConstructor.kt:30)
	at kotlin.reflect.jvm.internal.impl.descriptors.impl.AbstractTypeParameterDescriptor.getUpperBounds(AbstractTypeParameterDescriptor.java:119)
	at kotlin.reflect.jvm.internal.impl.load.java.typeEnhancement.SignatureEnhancement$SignatureParts.boundsNullability(signatureEnhancement.kt:445)
	at kotlin.reflect.jvm.internal.impl.load.java.typeEnhancement.SignatureEnhancement$SignatureParts.nullabilityInfoBoundsForTypeParameterUsage(signatureEnhancement.kt:428)
	at kotlin.reflect.jvm.internal.impl.load.java.typeEnhancement.SignatureEnhancement$SignatureParts.extractQualifiersFromAnnotations(signatureEnhancement.kt:358)
	at kotlin.reflect.jvm.internal.impl.load.java.typeEnhancement.SignatureEnhancement$SignatureParts.computeQualifiersForOverride(signatureEnhancement.kt:539)
	at kotlin.reflect.jvm.internal.impl.load.java.typeEnhancement.SignatureEnhancement$SignatureParts.computeIndexedQualifiersForOverride(signatureEnhancement.kt:479)
	at kotlin.reflect.jvm.internal.impl.load.java.typeEnhancement.SignatureEnhancement$SignatureParts.enhance(signatureEnhancement.kt:273)
	at kotlin.reflect.jvm.internal.impl.load.java.typeEnhancement.SignatureEnhancement.enhanceSignature(signatureEnhancement.kt:211)
	at kotlin.reflect.jvm.internal.impl.load.java.typeEnhancement.SignatureEnhancement.enhanceSignatures(signatureEnhancement.kt:151)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaClassMemberScope$constructors$1.invoke(LazyJavaClassMemberScope.kt:101)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaClassMemberScope$constructors$1.invoke(LazyJavaClassMemberScope.kt:83)
2024-01-23 10:33:42.736 19935-19991 EasyHttp D...pi@c16eb70 cn.smart.hospital                    E  	at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:408)
	at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedNotNullLazyValue.invoke(LockBasedStorageManager.java:527)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaClassDescriptor.getConstructors(LazyJavaClassDescriptor.kt:141)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaClassDescriptor.getConstructors(LazyJavaClassDescriptor.kt:44)
	at kotlin.reflect.jvm.internal.KClassImpl.getConstructorDescriptors(KClassImpl.kt:203)
	at kotlin.reflect.jvm.internal.KClassImpl$Data$constructors$2.invoke(KClassImpl.kt:94)
	at kotlin.reflect.jvm.internal.KClassImpl$Data$constructors$2.invoke(KClassImpl.kt:47)
	at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:92)
	at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:31)
	at kotlin.reflect.jvm.internal.KClassImpl$Data.getConstructors(Unknown Source:7)
	at kotlin.reflect.jvm.internal.KClassImpl.getConstructors(KClassImpl.kt:238)
	at kotlin.reflect.full.KClasses.getPrimaryConstructor(KClasses.kt:40)
	at com.hjq.gson.factory.constructor.KotlinDataClassDefaultValueConstructor.construct(KotlinDataClassDefaultValueConstructor.kt:25)
	at com.hjq.gson.factory.constructor.ReflectCreatorConstructor.construct(ReflectCreatorConstructor.java:28)
	at com.hjq.gson.factory.element.ReflectiveTypeAdapter.read(ReflectiveTypeAdapter.java:57)
	at com.google.gson.Gson.fromJson(Gson.java:1227)
	at com.google.gson.Gson.fromJson(Gson.java:1137)
	at com.google.gson.Gson.fromJson(Gson.java:1047)
	at com.google.gson.Gson.fromJson(Gson.java:1014)
	at cn.smart.hospital.http.model.RequestHandler.requestSuccess(RequestHandler.java:108)
	at com.hjq.http.callback.NormalCallback.onHttpResponse(NormalCallback.java:106)
	at com.hjq.http.callback.BaseCallback.onResponse(BaseCallback.java:72)
	at okhttp3.RealCall$AsyncCall.execute(RealCall.java:203)
	at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
	at java.lang.Thread.run(Thread.java:920)
2024-01-23 10:33:42.745 19935-19991 EasyHttp D...pi@c16eb70 cn.smart.hospital                    E  No virtual method getModule()Ljava/lang/Module; in class Ljava/lang/Class; or its super classes (declaration of 'java.lang.Class' appears in /apex/com.android.art/javalib/core-oj.jar)
com.hjq.http.exception.HttpException: No virtual method getModule()Ljava/lang/Module; in class Ljava/lang/Class; or its super classes (declaration of 'java.lang.Class' appears in /apex/com.android.art/javalib/core-oj.jar)
	at cn.smart.hospital.http.model.RequestHandler.requestFail(RequestHandler.java:155)
	at com.hjq.http.callback.NormalCallback.onHttpFailure(NormalCallback.java:145)
	at com.hjq.http.callback.BaseCallback.onResponse(BaseCallback.java:75)
	at okhttp3.RealCall$AsyncCall.execute(RealCall.java:203)
	at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)`
  • 降低 GsonFactory:9.5版本 9.3,9.2报一样的错误,9.0就能正常使用

复现步骤【必填】

  • 因为的项目没有办法升级到 EasyHttp demo 的最新 targetSdkVersion 31 的版本,直接跑 EasyHttp demo 是没有问题
apply plugin: 'com.android.application'

android {
    compileSdkVersion 28

    defaultConfig {
        versionName "1.0.5"
        versionCode 105
        targetSdkVersion 28
        applicationId "cn.smart.hospital"
        minSdkVersion 21
        multiDexEnabled false
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    lintOptions {
        abortOnError false
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

repositories {
    flatDir {
        dirs 'libs'
    }
}

// 这个plugin需要放在android配置之后,因为需要读取android中的配置项
apply plugin: 'replugin-plugin-gradle'

repluginPluginConfig {
    appModule = ':app'
    pluginName = "cn.smart.hospital" // 内容为该插件包名
    hostApplicationId = "com.huawei.smarthome.extend"
    hostAppLauncherActivity = "com.huawei.smarthome.login.LauncherActivity"
}

dependencies {
    implementation "com.qihoo360.replugin:replugin-plugin-lib-androidx:2.3.4"
    implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0'
    provided files('libs/fragment.jar')//这个jar就是从Support-fragment中提取出来的并非特制包目的是为了骗过编译期
    provided files('libs/common-utils-lib-1.0.0.jar')//这个jar就是从Host的utils中编译生成的,其目的是为了骗过编译期
    implementation(name: 'plugin-library', ext: 'aar')//sample:compile aar
    // mqtt
    implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.2'
    implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
    // 网络请求框架:https://github.com/getActivity/EasyHttp
    implementation 'com.github.getActivity:EasyHttp:12.8'
    implementation 'com.squareup.okhttp3:okhttp:3.12.13'
    // Gson 解析容错:https://github.com/getActivity/GsonFactory
    implementation 'com.github.getActivity:GsonFactory:9.0'
    // Json 解析框架:https://github.com/google/gson
    implementation 'com.google.code.gson:gson:2.10.1'
    // Kotlin 反射库:用于反射 Kotlin data class 类对象
    implementation 'org.jetbrains.kotlin:kotlin-reflect:1.5.10'
    //基础工具库
    implementation 'com.github.tamsiree.RxTool:RxKit:2.6.3'

    implementation 'io.github.jeremyliao:live-event-bus-x:1.8.0'
}

public class DeviceTypeApi implements IRequestApi {
    @NonNull
    @Override
    public String getApi() {
        return "api/p-szkj-select-device-type";
    }

    private String sn;

    public DeviceTypeApi setSn(String sn) {
        this.sn = sn;
        return this;
    }
    public final static class Bean {
        private String sn; // 设备码
        private int type; // 类型
        private String no; // 编号

        public String getSn() {
            return sn;
        }

        public int getType() {
            return type;
        }

        public String getNo() {
            return no;
        }
    }
}
String sn = RxSPTool.getContent(RxTool.getContext(), Constant.KEY_DEVICE_SN_NAME);
EasyHttp.get(this)
        .api(new DeviceTypeApi()
                .setSn(sn))
        .request(new HttpCallbackProxy<HttpData<DeviceTypeApi.Bean>>(this) {
            @Override
            public void onHttpSuccess(HttpData<DeviceTypeApi.Bean> result) {
                RxToast.showToastShort("Get 请求成功,请看日志");
            }
        });

是否必现【必填】

项目 targetSdkVersion【必填】

28

出现问题的手机信息【必填】

Android12 虚拟机

出现问题的安卓版本【必填】

Android12

问题信息的来源渠道【必填】

自己遇到的

是部分机型还是所有机型都会出现【必答】

全部

框架最新的版本是否存在这个问题【必答】

框架文档是否提及了该问题【必答】

是否已经查阅框架文档但还未能解决的【必答】

issue 列表中是否有人曾提过类似的问题【必答】

是否已经搜索过了 issue 列表但还未能解决的【必答】

是否可以通过 Demo 来复现该问题【必答】

提供报错堆栈

No response

提供截图或视频

No response

提供解决方案

No response

Gson版本升级到2.9.1之后ConstructorConstructor构造方法需要三个参数,望兼容

【警告:请务必按照 issue 模板填写,不要抱有侥幸心理,一旦发现 issue 没有按照模板认真填写,一律直接关闭】

问题描述

  • 框架版本【必填】:6.2

  • 问题描述【必填】:gson 2.9.1版本构造方法变更

  • 复现步骤【必填】:XXX(注意:目前不受理没有复现步骤的 Bug 单)

  • 是否必现【必填】:是

  • 出现问题的手机信息【必填】:请填写出现问题的品牌和机型

  • 出现问题的安卓版本【必填】:请填写出现问题的 Android 版本

请回答

  • 是部分机型还是所有机型都会出现【必答】:部分/全部(例如:某为,某 Android 版本会出现)

  • 框架最新的版本是否存在这个问题【必答】:是/否(如果用的是旧版本的话,建议升级看问题是否还存在)

  • 是否已经查阅框架文档还未能解决的【必答】:是/否(文档会提供最常见的问题解答,可以看看是否有自己想要的)

  • issue 是否有人曾提过类似的问题【必答】:是/否(看看曾经有人提过类似的问题,先参考一下别人是怎么解决的)

  • 使用原生的 Gson 是否也会出现该问题【必答】:是/否(排查一下是不是 GsonFactory 的代码存在问题导致的)

其他

  • 提供报错堆栈(如果有报错的话必填,注意不要拿被混淆过的代码堆栈上来)

  • 提供截图或视频(根据需要提供,此项不强制)

  • 提供解决方案(如果已经解决了的话,此项不强制)

[疑惑]:9.0升级9.2

问题描述【必填】

按照文档

// Gson 解析容错:https://github.com/getActivity/GsonFactory
implementation 'com.github.getActivity:GsonFactory:9.2'
// Json 解析框架:https://github.com/google/gson
implementation 'com.google.code.gson:gson:2.10.1'
// Kotlin 反射库:用于反射 Kotlin data class 类对象(新增依赖)
implementation 'org.jetbrains.kotlin:kotlin-reflect:1.5.10'

当我调用接口时返回错误:
ApiResponse#data,后台返回的条目类型为:BEGIN_OBJECT

这是我的代码:
login

框架文档是否提及了该问题【必答】

是否已经查阅框架文档但还未能解决的【必答】

issue 列表中是否有人曾提过类似的问题【必答】

是否已经搜索过了 issue 列表但还未能解决的【必答】

9.0升级9.3[Bug]:

框架版本【必填】

v9.3

问题描述【必填】

9.0升级9.3后 解析报错无法解析

复现步骤【必填】

image
image

是否必现【必填】

未选择

项目 targetSdkVersion【必填】

23

出现问题的手机信息【必填】

小米青春11

出现问题的安卓版本【必填】

13

问题信息的来源渠道【必填】

No response

是部分机型还是所有机型都会出现【必答】

跟机型没关系

框架最新的版本是否存在这个问题【必答】

未选择

框架文档是否提及了该问题【必答】

未选择

是否已经查阅框架文档但还未能解决的【必答】

未选择

issue 列表中是否有人曾提过类似的问题【必答】

未选择

是否已经搜索过了 issue 列表但还未能解决的【必答】

未选择

是否可以通过 Demo 来复现该问题【必答】

未选择

提供报错堆栈

{"code":2000,"msg":"success","data":{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJwaHBlcjY2Ni9qd3QiLCJ1c2VyX2lkIjoiMTIiLCJqd3Rfc2NlbmUiOiJkZWZhdWx0IiwianRpIjoiZGVmYXVsdF82NTk0ZDgzMjAzZTY3Ni4xOTQyNzk5OCIsImlhdCI6MTcwNDI1MzQ5MCwibmJmIjoxNzA0MjUzNDkwLCJleHAiOjE3MzYzOTQyOTB9.DeUkeOJslxiraqmuw5tnXQj0Qknh7OH-05ZoUiWJRSo","user_info":{"user_id":"12","mobile":"817612703911","username":"Ocean1234567890","regdate":"","avatar":"https:\/\/sg-small.voopoo.com.cn\/voopoo-club\/portrait\/202311\/07\/4d03b89f443b0b4d48f06497e9ec882e1699340148943.jpg","recommender":"","last_login_time":1704253490,"created_at":1639551834,"updated_at":1704253490,"role_id":1,"invite_num":0,"fcm_token":"d-MA5kjATc-rFBPGp76YOt:APA91bFSs1lT5XuCIuuaLOjofXcMfu1jAbbSuVkzj08RtrSATvDWkGKAviZofqt71Znq2HWWCFxA4MZ1ZaRZmUAvLUPVpi94A-sQhtcNVVvzTqdHvD2LSs6mdxyO7zJVmkfNWycXV380","salt":"a31d43","posts":25,"followers":12,"birth_year":1990,"birth_month":1,"birth_day":1,"gender":2,"is_gray":0,"email":"","deleted_at":null,"password":"6f5bae4c240b5dfef0d71c9d357f1372","platform":"2","last_ip":"192.168.12.212","info_status":1,"source":1,"avatar_status":1,"reg_ip":"103.162.172.86","app_version":"2.0.4","last_visit_time":1704253476}}}

提供截图或视频

image

提供解决方案

No response

关于JsonCallback关联功能的优化建以

建议收集

  • issue 是否有人曾提过类似的问题?(必答项,一旦出现重复提问我将不会再次解答)

  • 你觉得框架有什么不足之处?(必答项,你可以描述框架有什么令你不满意的地方)
    CollectionTypeAdapterFactory、ReflectiveTypeAdapterFactory 在 create 方法中,return TypeAdapter前未调用【setReflectiveType】方法,导致如果是整个类或者这个List转换错误的情况下,JsonCallback回调中前两个值都为null。
    举例:
    String value = "[{\"name\":\"张三\"}]"; IceVo iceVo = ...(转换代码)

    String value2 = "{\"name\":\"张三\"}"; List<IceVo> list = ...(转换代码)

    虽然应用到的可能性比较小,但是我觉得可以更完善一点吧。

  • 你觉得该怎么去完善会比较好?(非必答项,你可以提供一下自己的想法或者做法供作者参考)
    CollectionTypeAdapterFactory、ReflectiveTypeAdapterFactory 在 create 方法中,return TypeAdapter前调用【setReflectiveType】方法

[建议]:我想去掉这样的警告打印<init> argument 4 has type int, got null

你觉得框架有什么不足之处?【必答】

这样我的控制台会很乱,会和有用的信息混在一起

issue 是否有人曾提过类似的建议?【必答】

框架文档是否提及了该问题【必答】

是否已经查阅框架文档但还未能解决的【必答】

你觉得该怎么去完善会比较好?【非必答】

这块警告没有实质性的作用可以去掉

解析json数据问题

问题描述

  • 框架版本:GsonFactory版本:6.0 gson版本:2.9.0

  • 问题描述:在解析期望类型是LinkedTreeMap<String, String>,实际返回数据可能是null,空字符串,数组等类型,则会报错,具体使用json在相关文件中

  • 复现步骤:集成框架后,解析测试json数据

  • 是否必现:是

  • 出现问题的手机信息:模拟器Pixel 4,小米MI-4C

  • 出现问题的安卓版本:API29

请回答

  • 是部分机型还是所有机型都会出现:测试的机型都出现报错

  • 框架最新的版本是否存在这个问题:是

  • 是否已经查阅框架文档还未能解决的:是

  • issue 是否有人曾提过类似的问题:否

  • 使用原生的 Gson 是否也会出现该问题:是

其他

  • 提供报错堆栈:

  • E/CustomActivityOnCrash: App has crashed, executing CustomActivityOnCrash's UncaughtExceptionHandler
    com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 1069 path $.data.friends[1].friends[0].extra[0]
    at com.hjq.gson.factory.element.ReflectiveTypeAdapter.read(ReflectiveTypeAdapter.java:73)
    at com.google.gson.Gson$FutureTypeAdapter.read(Gson.java:1079)
    at com.hjq.gson.factory.element.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:34)
    at com.hjq.gson.factory.element.CollectionTypeAdapter.read(CollectionTypeAdapter.java:62)
    at com.hjq.gson.factory.element.CollectionTypeAdapter.read(CollectionTypeAdapter.java:23)
    at com.hjq.gson.factory.element.ReflectiveTypeUtils$1.read(ReflectiveTypeUtils.java:111)
    at com.hjq.gson.factory.element.ReflectiveTypeAdapter.read(ReflectiveTypeAdapter.java:71)
    at com.google.gson.Gson$FutureTypeAdapter.read(Gson.java:1079)
    at com.hjq.gson.factory.element.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:34)
    at com.hjq.gson.factory.element.CollectionTypeAdapter.read(CollectionTypeAdapter.java:62)
    at com.hjq.gson.factory.element.CollectionTypeAdapter.read(CollectionTypeAdapter.java:23)
    at com.hjq.gson.factory.element.ReflectiveTypeUtils$1.read(ReflectiveTypeUtils.java:111)
    at com.hjq.gson.factory.element.ReflectiveTypeAdapter.read(ReflectiveTypeAdapter.java:71)
    at com.hjq.gson.factory.element.ReflectiveTypeUtils$1.read(ReflectiveTypeUtils.java:111)
    at com.hjq.gson.factory.element.ReflectiveTypeAdapter.read(ReflectiveTypeAdapter.java:71)
    at com.google.gson.Gson.fromJson(Gson.java:991)
    at com.google.gson.Gson.fromJson(Gson.java:956)
    at com.google.gson.Gson.fromJson(Gson.java:905)
    at com.google.gson.Gson.fromJson(Gson.java:876)

  • 提供截图或视频(根据需要提供,此项不强制)
    相关文件.zip

  • 提供解决方案(如果已经解决了的话,此项不强制):小白一枚,不知道具体解决思路,只知道可能是AdapterFactory的问题

[建议]:兼容类型不匹配的情况

你觉得框架有什么不足之处?【必答】

建议容错库遇到类型匹配但解析错误的时候,也可以返回默认值
例子复现如下:

public class JsonBean {
    private ArrayList<Double> dataValList = new ArrayList<>();
}
String json = "{\n" +
                    "        \"id\": \"1704391195266473986\",\n" +
                    "        \"dataValList\":\n" +
                    "        [\n" +
                    "            \"null\"\n" +
                    "        ],\n" +
                    "    }";
JsonBean bean = GsonFactory.getSingletonGson().fromJson(json, JsonBean.class);

执行以上代码 会直接抛出错误.
在真实场景中请求一个接口返回一段json解析,如果因为解析其中一个字段就整体抛错的话,也会让程序停止进行不下去,这一点是否可以优化

issue 是否有人曾提过类似的建议?【必答】

框架文档是否提及了该问题【必答】

是否已经查阅框架文档但还未能解决的【必答】

你觉得该怎么去完善会比较好?【非必答】

No response

容错范围

【警告:请务必按照 issue 模板填写,不要抱有侥幸心理,一旦发现 issue 没有按照模板认真填写,一律直接关闭】

问题描述

  • 请描述一下你的疑惑【必填】:期待的是bean但是返回的是空字符串容错失败了。

请回答

  • issue 是否有人曾提过类似的问题?【必答】否

  • 框架文档是否有提及到此问题?【必答】:是
    hello,轮子哥,很感谢能开源这么多项目。我在使用容错项目前看到了项目简介容错支持bean。或者说是不兼容的类型直接不解析。我遇见的问题是这样的:retrofit请求使用的gson解析,baseresponse中泛型data对象有时候在接口校验失败之后,后台原先返回的data就会变成空字符串,这时候就会有问题因为baseresponse里面的泛型data通常是传一个bean进去,导致了解析异常报错。使用本框架还是没有容错,请问轮子哥这个场景在不在本框架的容错范围之内。

[疑惑]:关于readme写的为什么gson解析后,kotlin默认值无效的问题不太对

问题描述【必填】

在Gson反序列化的时候,它会使用无参构造函数来创建对象

data class User(val name: String = "张三", val age: Int = 18)

比如这个类,在编译后,这个类会有两个构造函数:一个是无参构造函数,另一个是有参构造函数。无参构造函数会使用默认值也就是null来初始化属性,有参构造函数会使用传入的参数来初始化属性。

框架文档是否提及了该问题【必答】

是否已经查阅框架文档但还未能解决的【必答】

issue 列表中是否有人曾提过类似的问题【必答】

是否已经搜索过了 issue 列表但还未能解决的【必答】

后台成功与失败返回类型不一致的问题

【警告:请务必按照 issue 模板填写,不要抱有侥幸心理,一旦发现 issue 没有按照模板认真填写,一律直接关闭】

建议收集

  • issue 是否有人曾提过类似的问题?【必答】否

  • 你觉得框架有什么不足之处?【必答】 后台返回的错误数据结构与实体类不一致,如果使用了该lib,那么就会被容错了,获取到的对象是空的,比如后台返回的正确的是{"code":200,
    "result":{"banner":"1"} }而错误的是{"code":500,
    "result":"网络出现了异常"},我需要吐司出来这个result数据,那么使用该lib 我获取到的result就是空的

  • 你觉得该怎么去完善会比较好?【非必答】

  • 是否可以提交一个接口让开发者单独对其做出处理?

服务端没有返回相应的字段数据

Class Test { String name; String age; }

您好,请问下这么一个例子,服务端只有返回name 这个字段数据,导致age为null,(反序列化时,类中有但Json中没有的字段将设值为null。)我想对age进行不为null处理,应该怎么做呢

[Bug]:com.google.gson.internal.ConstructorConstructor$9.construct (ConstructorConstructor.java:262)

框架版本【必填】

6.5

问题描述【必填】

com.google.gson.internal.ConstructorConstructor$9.construct (ConstructorConstructor.java:262)
com.hjq.gson.factory.element.ReflectiveTypeAdapter.read (ReflectiveTypeAdapter.java:58)
com.hjq.gson.factory.element.ReflectiveTypeUtils$1.read (ReflectiveTypeUtils.java:111)
com.hjq.gson.factory.element.ReflectiveTypeAdapter.read (ReflectiveTypeAdapter.java:71)
com.hjq.gson.factory.element.TypeAdapterRuntimeTypeWrapper.read (TypeAdapterRuntimeTypeWrapper.java:35)
com.hjq.gson.factory.element.CollectionTypeAdapter.read (CollectionTypeAdapter.java:62)
com.hjq.gson.factory.element.CollectionTypeAdapter.read (CollectionTypeAdapter.java:23)
com.hjq.gson.factory.element.ReflectiveTypeUtils$1.read (ReflectiveTypeUtils.java:111)
com.hjq.gson.factory.element.ReflectiveTypeAdapter.read (ReflectiveTypeAdapter.java:71)
com.hjq.gson.factory.element.TypeAdapterRuntimeTypeWrapper.read (TypeAdapterRuntimeTypeWrapper.java:35)
com.hjq.gson.factory.element.CollectionTypeAdapter.read (CollectionTypeAdapter.java:62)
com.hjq.gson.factory.element.CollectionTypeAdapter.read (CollectionTypeAdapter.java:23)
com.google.gson.Gson$FutureTypeAdapter.read (Gson.java:1367)
com.hjq.gson.factory.element.ReflectiveTypeUtils$1.read (ReflectiveTypeUtils.java:111)
com.hjq.gson.factory.element.ReflectiveTypeAdapter.read (ReflectiveTypeAdapter.java:71)
com.hjq.gson.factory.element.TypeAdapterRuntimeTypeWrapper.read (TypeAdapterRuntimeTypeWrapper.java:35)
com.hjq.gson.factory.element.CollectionTypeAdapter.read (CollectionTypeAdapter.java:62)
com.hjq.gson.factory.element.CollectionTypeAdapter.read (CollectionTypeAdapter.java:23)
com.hjq.gson.factory.element.ReflectiveTypeUtils$1.read (ReflectiveTypeUtils.java:111)
com.hjq.gson.factory.element.ReflectiveTypeAdapter.read (ReflectiveTypeAdapter.java:71)
com.google.gson.Gson.fromJson (Gson.java:1227)
com.google.gson.Gson.fromJson (Gson.java:1137)
com.google.gson.Gson.fromJson (Gson.java:1047)
com.google.gson.Gson.fromJson (Gson.java:1014)

复现步骤【必填】

是否必现【必填】

项目 targetSdkVersion【必填】

31

出现问题的手机信息【必填】

Galaxy A02

出现问题的安卓版本【必填】

7

问题信息的来源渠道【必填】

其他渠道

是部分机型还是所有机型都会出现【必答】

全部

框架最新的版本是否存在这个问题【必答】

框架文档是否提及了该问题【必答】

是否已经查阅框架文档但还未能解决的【必答】

issue 列表中是否有人曾提过类似的问题【必答】

是否已经搜索过了 issue 列表但还未能解决的【必答】

是否可以通过 Demo 来复现该问题【必答】

提供报错堆栈

No response

提供截图或视频

c2fd3726cc037bd23fad2f71f8b84796

提供解决方案

No response

[疑惑]:

问题描述【必填】

大佬,我能在整个解析过程中,获取到一个在JavaBean中未定义的属性值吗?比如后端返回的结构体中统一增加了一个tr的字段,但是我所有的Java Bean (Data Class)都没有定义这个字段,按照Gson的解析流程会将未定义的字段都过滤掉,但是我这时想要拿到这个tr字段,应该如何做呢?

框架文档是否提及了该问题【必答】

是否已经查阅框架文档但还未能解决的【必答】

issue 列表中是否有人曾提过类似的问题【必答】

是否已经搜索过了 issue 列表但还未能解决的【必答】

能否通过getDelegateAdapter方法给所有TypeAdapter都套层代理,出错时直接跳到下一个呢

【警告:请务必按照 issue 模板填写,不要抱有侥幸心理,一旦发现 issue 没有按照模板认真填写,一律直接关闭】

问题描述

大佬您好:
在阅读源码时,偶然发现在Gson.class下,跟getAdapter同级有一个getDelegateAdapter的方法,它的作用是可以给所有的TypeAdapter设置代理类,这样就可以拦截TypeAdapter出错时的动作,比如下面类似代码:

{
    val gson = GsonBuilder().registerTypeAdapterFactory(StrongTypeAdapterFactory()).create()
    class StrongTypeAdapterFactory : TypeAdapterFactory {
        override fun <T> create(gson: Gson, type: TypeToken<T>): TypeAdapter<T> {
            // 给每一个目标TypeAdapter都嵌套一个代理,可以主动拦截其结果
            val adapter: TypeAdapter<T> = gson.getDelegateAdapter(this, type)

            return object : TypeAdapter<T>() {
                @Throws(IOException::class)
                override fun write(out: JsonWriter, value: T?) {
                    adapter.write(out, value)
                }

                @Throws(IOException::class)
                override fun read(reader: JsonReader): T? {
                    return try {
                        // 原始目标adapter反序列化
                        adapter.read(reader)
                    } catch (e: Throwable) {
                        // 只要有报错的并且还有下一个就执行跳过操
                        if (reader.hasNext()) {
                            reader.skipValue()
                        }
                        null
                    }
                }
            }
        }
    }
}

这样是不是就能简单粗暴的搞定所有的容错呢。

请回答

  • issue 是否有人曾提过类似的问题?【必答】 没有

  • 框架文档是否有提及到此问题?【必答】:否

库非常不错,但问题不是个好问题

路过这个 repo 老多次,但是还是忍不住说一两句:

大佬的库非常不错,但是背景问题不是个好问题。

大家可能觉得 Gson 解析容错没什么,那是因为我们对 Gson 解析失败的场景没有了解过:
类型不对:后台有数据时返回 JsonObject,没数据返回 [],Gson 会直接抛出异常
措手不及:如果客户端定义的是整数,但是后台返回浮点数,Gson 会直接抛出异常
意想不到:如果客户端定义的是布尔值,但是后台返回的是 0 或者 1,Gson 会直接抛出异常

这种情况下的后端已经违背了最最基本的要求,即 按照 contract 输出结果
所以这里的责任首先在后端,而不是客户端;

从修改的容易程度和特点来说,也应该是后端来处理这种问题——
因为客户端的控制权在用户手里,新版一旦发出去,其改动就非常困难,用户可以拒绝新版的改动,使用旧版本;
但是后端可以随时上线,出现问题之后可以随时改动,随时发版,随时 hotfix(虽然这个随时不太人道,但是从根本上来说是可以做到的,而客户端要等待新版审核,修改生效的时间甚至要拉长到一周到两周)

有没有必要处理 Json 解析容错?
我觉得非常有必要,因为后台返回的数据结构是什么样我们把控不了,但是有一点是肯定的,我们都不希望它崩,因为一个接口的失败导致整个 App 崩溃退出实属不值得,但是 Gson 很敏感,动不动就崩。

当然,我们都不希望程序崩溃,但是一个 Gson 解析失败就会导致程序崩溃吗?或者说 Gson 崩溃就一定要导致 App 崩溃吗?
当然不是,我们应该对网络请求部分进行 try-catch,这样即使抛异常了,App 也不会崩溃,还可以根据异常显示一个用户友好的提示界面,然后把锅丢给后端去改。(毕竟这是后端的责任)
如果觉得到处写 try-catch 不容易,也可以统一设定 ExceptionHandler,不管是 RxJava 还是 Kotlin Coroutine 都有与之对应的方案。


Gson 采用的是 let-it-fail 的策略,本来这种 与 contract 不符 的情况就应该要 fail,只有 fail 了,才能让开发人员尽早发现,尽早解决问题;
但是大佬的库实际上是将问题隐藏了起来,同时也对后端返回的数据进行了修改

如果后台返回的类型和客户端定义的类型不匹配,框架就不解析这个字段
如果客户端定义的是整数,但后台返回浮点数,框架就对数值进行取整并赋值给字段
如果客户端定义布尔值,但是后台返回整数,框架则将非 0 的数值则赋值为 true,否则为 false

这样说实话如果不熟悉这个框架的新人接手这个项目,查问题的时候显然要走点弯路。

举个这么个场景:

如果客户端定义的是整数,但后台返回浮点数,框架就对数值进行取整并赋值给字段

浮点数的取整是有很多方法的,例如四舍五入取整,进一取整,抹除小数部分保留整数部分等等;
有些时候根据不同的情况需要对浮点数进行不同的取整方式

如果客户端定义布尔值,但是后台返回整数,框架则将非 0 的数值则赋值为 true,否则为 false

当然,后台正常的时候返回 0 和 1,但是这个字段对应的服务崩溃了,然后后台处理了一下反了一个 -1;
这个时候 -1 到底是 true 还是 false,就需要看情况来定了。


当然,我也待过那种前端弱势,后端强势的公司,说什么都不改,问就是改不了,不好改;
这个时候我觉得应该跑路了,这种垃圾公司待着也没什么用

[Bug]:result返回为空时出现java.lang.ClassCastException异常,具体返回格式看描述

框架版本【必填】

9.6

问题描述【必填】

{"message":"操作成功","code":"A000","result":{"count":"15"}}

{"message":"操作成功","code":"A000","result":null}
java.lang.ClassCastException: java.lang.Object cannot be cast to com.xxxx.ben.xxxx

复现步骤【必填】

{"message":"操作成功","code":"A000","result":null} result为null时必现

是否必现【必填】

项目 targetSdkVersion【必填】

33

出现问题的手机信息【必填】

红米K30Pro

出现问题的安卓版本【必填】

12

问题信息的来源渠道【必填】

自己遇到的

是部分机型还是所有机型都会出现【必答】

全部

框架最新的版本是否存在这个问题【必答】

框架文档是否提及了该问题【必答】

是否已经查阅框架文档但还未能解决的【必答】

issue 列表中是否有人曾提过类似的问题【必答】

是否已经搜索过了 issue 列表但还未能解决的【必答】

是否可以通过 Demo 来复现该问题【必答】

提供报错堆栈

No response

提供截图或视频

No response

提供解决方案

No response

建议适配kotlin默认值

【警告:请务必按照 issue 模板填写,不要抱有侥幸心理,一旦发现 issue 没有按照模板认真填写,一律直接关闭】

建议收集

  • issue 是否有人曾提过类似的问题?【必答】 #4 有人提出过类似的疑问

  • 框架文档是否有提及到此问题?【必答】:否

  • 你觉得框架有什么不足之处?【必答】

框架的容错特性确实很不错 考虑到目前kotlin开发占比很高
而kotlin在定义data class时候给默认值是比较常规的做法
很大一部分人还是通过Gson来配合retrofit 但目前的Gson不完全支持默认值
核心代码:

Object fieldValue = typeAdapter.read(reader);
if (fieldValue != null || !isPrimitive) {
    field.set(value, fieldValue);
}

当为非基本类型时候 会强制赋值 导致默认值失效
如果可以适配kotlin的默认值情况 能解决 设置了默认值 还是非空类型 还要必须判空的情况

  • 你觉得该怎么去完善会比较好?【非必答】

建议:如果强制更改这一段赋值逻辑 可能就不是“原汁原味”的Gson了 改动有点大 不一定大家都能接受
所以在初始化的时候给一个配置 可以开启支持kotlin默认值 可能是比较好的做法
核心代码:

Object fieldValue = typeAdapter.read(reader);
if (fieldValue != null) {
    field.set(value, fieldValue);
} else if (!isPrimitive) {
    if (field.get(value) == null) {
        field.set(value, null);
    }
}

[疑惑]:不知道怎么写标题,看描述吧

问题描述【必填】

{"message":"操作成功","code":"A000","result":{"count":"15"}}

{"message":"操作成功","code":"A000","result":null}

框架是否支持result为null的情况,我接入的测试的时候遇到接口返回result为null的抛出ClassCastException异常,其他接口result返回数据时没有问题
java.lang.ClassCastException: java.lang.Object cannot be cast to com.xxxx.ben.xxxx

框架文档是否提及了该问题【必答】

是否已经查阅框架文档但还未能解决的【必答】

issue 列表中是否有人曾提过类似的问题【必答】

是否已经搜索过了 issue 列表但还未能解决的【必答】

[疑惑]:在解析过程中能否给所有的Java Bean或 data class 添加一个未定义的字段

问题描述【必填】

大佬,我能在整个解析过程中,获取到一个在Java Bean中未定义的属性值吗?
比如由于业务需要,后端在返回的结构体最外层统一新增加了一个tr的字段,但是我所有的Java Bean (Data Class)都未定义这个字段,按照Gson的解析流程会将未定义的字段都过滤掉,但是我这时想要拿到这个tr字段,并将这个字段添加给每一层级的Java Bean。

大致流程如下,原始Json是这样的

{
        "tr":"tr_map_value",
        "data": {
            "noticeMsgNum": "208",
            "order":{
                "orderId":"10086"
            }
        }
 }

但我想得到这样Json解析出来的结果

{
        "tr":"tr_map_value",
        "data": {
        "tr":"tr_map_value",
        "noticeMsgNum": "208", 
        "order":{
            "tr":"tr_map_value", 
            "orderId":"10086"
           }
        }
}

想了半天,如果想要统一处理,好像只能在解析这一步做操作了。但搞了半天一点头绪都没有,所以想问问大佬您能给些建议吗

框架文档是否提及了该问题【必答】

是否已经查阅框架文档但还未能解决的【必答】

issue 列表中是否有人曾提过类似的问题【必答】

是否已经搜索过了 issue 列表但还未能解决的【必答】

[Bug]:开启混淆后,Kotlin的data class 内部类解析失败。

框架版本【必填】

9.6

问题描述【必填】

开启混淆后,Kotlin的data class 内部类解析失败。

复现步骤【必填】

创建一个kotlin 文件
在其中定义多个data class ,并且相互有所引用,使用@SerializedName方法进行注解。
开启混淆,解析对应代码。

是否必现【必填】

项目 targetSdkVersion【必填】

33

出现问题的手机信息【必填】

全部

出现问题的安卓版本【必填】

全部

问题信息的来源渠道【必填】

自己遇到的

是部分机型还是所有机型都会出现【必答】

全部

框架最新的版本是否存在这个问题【必答】

框架文档是否提及了该问题【必答】

是否已经查阅框架文档但还未能解决的【必答】

issue 列表中是否有人曾提过类似的问题【必答】

是否已经搜索过了 issue 列表但还未能解决的【必答】

是否可以通过 Demo 来复现该问题【必答】

提供报错堆栈

2024-04-09 19:18:54.732  6374-16483 System.err              com.wepie.wespy                      W  java.lang.ClassNotFoundException: Didn't find class "com.wepie.wespy.module.party.home.PartyShareData" on path: DexPathList[[zip file "/data/app/~~UzbQn9r_moNkE7-KSr4Snw==/com.wepie.wespy-PAPtm3RmfiEAj_iMkz4ovw==/base.apk"],nativeLibraryDirectories=[/data/app/~~UzbQn9r_moNkE7-KSr4Snw==/com.wepie.wespy-PAPtm3RmfiEAj_iMkz4ovw==/lib/arm64, /data/app/~~UzbQn9r_moNkE7-KSr4Snw==/com.wepie.wespy-PAPtm3RmfiEAj_iMkz4ovw==/base.apk!/lib/arm64-v8a, /system/lib64, /system_ext/lib64]]
2024-04-09 19:18:54.732  6374-6374  SurfaceControl          com.wepie.wespy                      I   setExtendedRangeBrightness sc=Surface(name=com.wepie.wespy/com.wepie.wespy.module.party.home.PartyHomeActivity)/@0x25d32fc,currentBufferRatio=1.0,desiredRatio=1.0
2024-04-09 19:18:54.732  6374-16483 System.err              com.wepie.wespy                      W  	at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:259)
2024-04-09 19:18:54.732  6374-16483 System.err              com.wepie.wespy                      W  	at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at kotlin.reflect.jvm.internal.KDeclarationContainerImpl.parseType(KDeclarationContainerImpl.kt:266)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at kotlin.reflect.jvm.internal.KDeclarationContainerImpl.loadParameterTypes(KDeclarationContainerImpl.kt:257)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at kotlin.reflect.jvm.internal.KDeclarationContainerImpl.findConstructorBySignature(KDeclarationContainerImpl.kt:228)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at kotlin.reflect.jvm.internal.KFunctionImpl$caller$2.invoke(KFunctionImpl.kt:67)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at kotlin.reflect.jvm.internal.KFunctionImpl$caller$2.invoke(KFunctionImpl.kt:36)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at kotlin.reflect.jvm.internal.ReflectProperties$LazyVal.invoke(ReflectProperties.java:62)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:31)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at kotlin.reflect.jvm.internal.KFunctionImpl.getCaller(Unknown Source:7)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at kotlin.reflect.jvm.ReflectJvmMapping.getJavaMethod(ReflectJvmMapping.kt:63)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at kotlin.reflect.jvm.KCallablesJvm.setAccessible(KCallablesJvm.kt:82)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at com.hjq.gson.factory.constructor.KotlinDataClassDefaultValueConstructor.construct(KotlinDataClassDefaultValueConstructor.kt:29)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at com.hjq.gson.factory.constructor.l.construct(ReflectCreatorConstructor.java:29)
2024-04-09 19:18:54.733  6374-16662 BLASTBufferQueue        com.wepie.wespy                      D  [VRI[PartyHomeActivity]#15](f:0,a:1) acquireNextBufferLocked size=24x24 mFrameNumber=1 applyTransaction=true mTimestamp=108821324931038(auto) mPendingTransactions.size=0 graphicBufferId=27376121544767 transform=0
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at com.hjq.gson.factory.b.e.read(ReflectiveTypeAdapter.java:58)
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at com.hjq.gson.factory.c.c$1.a(ReflectiveTypeUtils.java:110)
2024-04-09 19:18:54.734  6374-16662 VRI[PartyHomeActivity]  com.wepie.wespy                      D  Received frameCommittedCallback lastAttemptedDrawFrameNum=1 didProduceBuffer=true syncBuffer=false
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at com.hjq.gson.factory.b.e.read(ReflectiveTypeAdapter.java:71)
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at com.hjq.gson.factory.c.c$1.a(ReflectiveTypeUtils.java:110)
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at com.hjq.gson.factory.b.e.read(ReflectiveTypeAdapter.java:71)
2024-04-09 19:18:54.734  6374-6374  VRI[PartyHomeActivity]  com.wepie.wespy                      D  draw finished.
2024-04-09 19:18:54.734  6374-6374  VRI[PartyHomeActivity]  com.wepie.wespy                      D  reportDrawFinished
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at com.google.gson.Gson.fromJson(Gson.java:1227)
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at com.google.gson.Gson.fromJson(Gson.java:1329)
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at com.google.gson.Gson.fromJson(Gson.java:1300)
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at com.three.http.callback.DataCallback.parseResponse(DataCallback.java:74)
2024-04-09 19:18:54.734  6374-6374  ViewRootImplExtImpl     com.wepie.wespy                      D  setMaxDequeuedBufferCount: 2
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at com.three.http.core.HttpUtil$3.onResponse(HttpUtil.java:288)
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174)
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
2024-04-09 19:18:54.735  6374-16483 System.err              com.wepie.wespy                      W  	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
2024-04-09 19:18:54.735  6374-16483 System.err              com.wepie.wespy                      W  	at java.lang.Thread.run(Thread.java:1012)

提供截图或视频

No response

提供解决方案

堆栈中的com.wepie.wespy.module.party.home.PartyShareData是原类名,但是被混淆了。通过反编译kotlin的字节码发现里面确实有一些反射代码,所以理论上keep一下就可以。

可以通过添加混淆规则解决,但是看堆栈还是报在了sdk这里,正常java类直接这样用没什么问题,还是想知道与根本原因.
目前使用8.0版本也无该问题。

根据demo差异,发现我们并未使用kotlin的kotlin-reflect库,有空后排查一下这里。

Gson 2.9.0兼容性问题

问题描述

Gson 2.9.0
ConstructorConstructor()构造多了一个参数
而GsonFactory用的是单构造的ConstructorConstructor(),要不要考虑兼容一下
Gson无法代码判断版本号,这个兼容只能用反射实现?判断这个构造方法是一个参数还是两个参数?
想不到什么更好的方案

  • 框架版本:com.github.getActivity:GsonFactory:5.2

  • 问题描述:
    ConstructorConstructor constructor = new ConstructorConstructor(INSTANCE_CREATORS);

  • 复现步骤:使用'com.google.code.gson:gson:2.9.0'

  • 是否必现:是

[Bug]:从 9.0 升级 9.3 出现崩溃

框架版本【必填】

9.3

问题描述【必填】

json解析问题

复现步骤【必填】

abstract class BaseResponse<T> {
    abstract fun isSuccess(): Boolean

    abstract fun getResponseCode(): Int

    abstract fun getResponseData(): T?

    abstract fun getResponseExtra(): Extra?

    abstract fun getResponseMessage(): String?

    abstract fun getResponsePath(): String?

    abstract fun getResponseTimestamp(): Any?

    abstract fun getResponseVersion(): String?
}
data class Extra(
    val errorMsg: String?
)
data class ApiResponse<T>(
    val code: Int?,
    val data: T?,
    val extra: Extra?,
    val message: String?,
    val path: String?,
    val timestamp: Any?,
    val version: String?,
) : BaseResponse<T>() {

    override fun isSuccess(): Boolean = code == 0

    override fun getResponseCode(): Int = code ?: -1

    override fun getResponseData(): T? = data

    override fun getResponseExtra(): Extra? = extra

    override fun getResponseMessage(): String? = message

    override fun getResponsePath(): String? = path

    override fun getResponseTimestamp(): Any? = timestamp

    override fun getResponseVersion(): String? = version
}

json如下

{
  "code": 0,
  "data": {
    "datas": [
      {
        "groupId": "1726920869317746689",
        "groupImg": "https://oss.bilinl.com/files/OSS_1607632797885739008/758500106313318471893a4e89.png",
        "groupName": "预警机器人的群",
        "groupNum": 16,
        "groupType": 0
      },
      {
        "groupId": "1724676352415760385",
        "groupImg": "https://oss.bilinl.com/files/OSS_1607632797885739008/467635091659571222b5249583.png",
        "groupName": "日报周报统计群",
        "groupNum": 93,
        "groupType": 0
      },
      {
        "groupId": "1722155428100882433",
        "groupImg": "https://oss.bilinl.com/files/OSS_1607632797885739008/28490015896166408679bad795.JPEG",
        "groupName": "呼呼和",
        "groupNum": 17,
        "groupType": 0
      },
      {
        "groupId": "1717475646627946497",
        "groupImg": "https://oss.bilinl.com/files/2022/10/18/2268350967832576e8f3005bb8.png",
        "groupName": "测试群",
        "groupNum": 5,
        "groupType": 0
      },
      {
        "groupId": "1717475641447981058",
        "groupImg": "https://oss.bilinl.com/files/2022/10/18/2268350967832576e8f3005bb8.png",
        "groupName": "测试群",
        "groupNum": 5,
        "groupType": 0
      },
      {
        "groupId": "1717475636247044097",
        "groupImg": "https://oss.bilinl.com/files/2022/10/18/2268350967832576e8f3005bb8.png",
        "groupName": "测试群",
        "groupNum": 5,
        "groupType": 0
      },
      {
        "groupId": "1717475631025135618",
        "groupImg": "https://oss.bilinl.com/files/2022/10/18/2268350967832576e8f3005bb8.png",
        "groupName": "测试群",
        "groupNum": 5,
        "groupType": 0
      },
      {
        "groupId": "1717475625782255617",
        "groupImg": "https://oss.bilinl.com/files/2022/10/18/2268350967832576e8f3005bb8.png",
        "groupName": "测试群",
        "groupNum": 5,
        "groupType": 0
      },
      {
        "groupId": "1717475620543569922",
        "groupImg": "https://oss.bilinl.com/files/2022/10/18/2268350967832576e8f3005bb8.png",
        "groupName": "测试群",
        "groupNum": 5,
        "groupType": 0
      },
      {
        "groupId": "1717475614512160770",
        "groupImg": "https://oss.bilinl.com/files/2022/10/18/2268350967832576e8f3005bb8.png",
        "groupName": "测试群",
        "groupNum": 5,
        "groupType": 0
      },
      {
        "groupId": "1717475609080537090",
        "groupImg": "https://oss.bilinl.com/files/2022/10/18/2268350967832576e8f3005bb8.png",
        "groupName": "测试群",
        "groupNum": 5,
        "groupType": 0
      },
      {
        "groupId": "1717475603145596930",
        "groupImg": "https://oss.bilinl.com/files/2022/10/18/2268350967832576e8f3005bb8.png",
        "groupName": "测试群",
        "groupNum": 5,
        "groupType": 0
      },
      {
        "groupId": "1717475597814636545",
        "groupImg": "https://oss.bilinl.com/files/2022/10/18/2268350967832576e8f3005bb8.png",
        "groupName": "测试群",
        "groupNum": 5,
        "groupType": 0
      },
      {
        "groupId": "1717475592550785025",
        "groupImg": "https://oss.bilinl.com/files/2022/10/18/2268350967832576e8f3005bb8.png",
        "groupName": "测试群",
        "groupNum": 5,
        "groupType": 0
      },
      {
        "groupId": "1717475587261767681",
        "groupImg": "https://oss.bilinl.com/files/2022/10/18/2268350967832576e8f3005bb8.png",
        "groupName": "测试群",
        "groupNum": 5,
        "groupType": 0
      },
      {
        "groupId": "1717475582031470594",
        "groupImg": "https://oss.bilinl.com/files/2022/10/18/2268350967832576e8f3005bb8.png",
        "groupName": "测试群",
        "groupNum": 5,
        "groupType": 0
      },
      {
        "groupId": "1717475576830533633",
        "groupImg": "https://oss.bilinl.com/files/2022/10/18/2268350967832576e8f3005bb8.png",
        "groupName": "测试群",
        "groupNum": 5,
        "groupType": 0
      },
      {
        "groupId": "1717475571650568193",
        "groupImg": "https://oss.bilinl.com/files/2022/10/18/2268350967832576e8f3005bb8.png",
        "groupName": "测试群",
        "groupNum": 5,
        "groupType": 0
      },
      {
        "groupId": "1717475566403493890",
        "groupImg": "https://oss.bilinl.com/files/2022/10/18/2268350967832576e8f3005bb8.png",
        "groupName": "测试群",
        "groupNum": 5,
        "groupType": 0
      },
      {
        "groupId": "1717475561185779713",
        "groupImg": "https://oss.bilinl.com/files/2022/10/18/2268350967832576e8f3005bb8.png",
        "groupName": "测试群",
        "groupNum": 5,
        "groupType": 0
      }
    ],
    "empty": false,
    "total": 875
  },
  "extra": null,
  "message": "success",
  "path": null,
  "timestamp": 1704182713739
}

报错信息如下

1704183212596

是否必现【必填】

项目 targetSdkVersion【必填】

33

出现问题的手机信息【必填】

小米mix2、逍遥模拟器(android 9版本)

出现问题的安卓版本【必填】

Android 9

问题信息的来源渠道【必填】

自己遇到的

是部分机型还是所有机型都会出现【必答】

目前仅测试小米mix2、逍遥模拟器(android 9版本)

框架最新的版本是否存在这个问题【必答】

框架文档是否提及了该问题【必答】

是否已经查阅框架文档但还未能解决的【必答】

issue 列表中是否有人曾提过类似的问题【必答】

是否已经搜索过了 issue 列表但还未能解决的【必答】

是否可以通过 Demo 来复现该问题【必答】

提供报错堆栈

No response

提供截图或视频

No response

提供解决方案

No response

谢谢轮子哥解决了我的问题!!

我们登录接口后台应该返回实体对象类型,在code码错误时,后台返回的字符串,导致我这一直报错,在网上找了好多都解决不了,用了轮子哥这个直接帮我解决了,轮子哥太强大了!!

请问此框架是不是不支持Map类型数据?

在使用此框架的容错机制时,现data数据中存在键名为extra,类型为LinkedTreeMap的值,实际返回数据可能是map类型,也可能是数组类型,这是解析会报错。

  • 框架版本:com.github.getActivity:GsonFactory:6.0

  • 问题描述:问题描述如上
    具体调用代码:GsonFactory.newGsonBuilder().create().fromJson(data, DataBean::class.java)
    DataBean是实际的数据bean对象

  • 复现步骤:使用'com.google.code.gson:gson:2.9.0'

  • 是否必现:是

  • 出现问题的手机信息:模拟器Pixel 4 API29

  • 出现问题的安卓版本:API29

json数据如下:
{
"code": 1,
"msg": "success",
"data": {
"name": "zhangsan",
"age": 10,
"sex": "male",
"score": 100,
"info": {
},
"friends": [
{
"name": "lisi",
"age": 11,
"sex": "female",
"friends": "",
"score": "80",
"info": {
"address": "2333",
"phone": "12345353"
},
"grade": [
100,
90,
89,
88
],
"extra": {
},
"data": {
"name": "lisi"
}
},
{
"name": "wangwu",
"age": 11,
"sex": "male",
"score": "90",
"info": "",
"grade": [
],
"data": [
{
"name": "lisi"
},
{
"name": "wangwu"
}
],
"extra": {
"111": "222"
},
"friends": [
{
"name": "zhaoliu",
"age": 12,
"sex": "male",
"score": 78,
"friends": [
],
"data": "data",
"extra": [
{
"33": "44"
}
],
"grade": "",
"info": [
{
"address": "123e4",
"phone": "123333"
}
]
},
{
"name": "laoba",
"age": 13,
"sex": "female",
"score": 88,
"friends": {
},
"extra": [
],
"grade": {
},
"info": null
}
]
}
]
}
}

[Bug]:开启混淆后,Kotlin的data class 内部类解析失败。

框架版本【必填】

9.6

问题描述【必填】

开启混淆后,Kotlin的data class 内部类解析失败。

复现步骤【必填】

创建一个kotlin 文件
在其中定义多个data class ,并且相互有所引用,使用@SerializedName方法进行注解。
开启混淆,解析对应代码。

是否必现【必填】

项目 targetSdkVersion【必填】

33

出现问题的手机信息【必填】

全部

出现问题的安卓版本【必填】

全部

问题信息的来源渠道【必填】

No response

是部分机型还是所有机型都会出现【必答】

全部

框架最新的版本是否存在这个问题【必答】

框架文档是否提及了该问题【必答】

是否已经查阅框架文档但还未能解决的【必答】

issue 列表中是否有人曾提过类似的问题【必答】

是否已经搜索过了 issue 列表但还未能解决的【必答】

是否可以通过 Demo 来复现该问题【必答】

提供报错堆栈

2024-04-09 19:18:54.732  6374-16483 System.err              com.wepie.wespy                      W  java.lang.ClassNotFoundException: Didn't find class "com.wepie.wespy.module.party.home.PartyShareData" on path: DexPathList[[zip file "/data/app/~~UzbQn9r_moNkE7-KSr4Snw==/com.wepie.wespy-PAPtm3RmfiEAj_iMkz4ovw==/base.apk"],nativeLibraryDirectories=[/data/app/~~UzbQn9r_moNkE7-KSr4Snw==/com.wepie.wespy-PAPtm3RmfiEAj_iMkz4ovw==/lib/arm64, /data/app/~~UzbQn9r_moNkE7-KSr4Snw==/com.wepie.wespy-PAPtm3RmfiEAj_iMkz4ovw==/base.apk!/lib/arm64-v8a, /system/lib64, /system_ext/lib64]]
2024-04-09 19:18:54.732  6374-6374  SurfaceControl          com.wepie.wespy                      I   setExtendedRangeBrightness sc=Surface(name=com.wepie.wespy/com.wepie.wespy.module.party.home.PartyHomeActivity)/@0x25d32fc,currentBufferRatio=1.0,desiredRatio=1.0
2024-04-09 19:18:54.732  6374-16483 System.err              com.wepie.wespy                      W  	at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:259)
2024-04-09 19:18:54.732  6374-16483 System.err              com.wepie.wespy                      W  	at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at kotlin.reflect.jvm.internal.KDeclarationContainerImpl.parseType(KDeclarationContainerImpl.kt:266)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at kotlin.reflect.jvm.internal.KDeclarationContainerImpl.loadParameterTypes(KDeclarationContainerImpl.kt:257)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at kotlin.reflect.jvm.internal.KDeclarationContainerImpl.findConstructorBySignature(KDeclarationContainerImpl.kt:228)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at kotlin.reflect.jvm.internal.KFunctionImpl$caller$2.invoke(KFunctionImpl.kt:67)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at kotlin.reflect.jvm.internal.KFunctionImpl$caller$2.invoke(KFunctionImpl.kt:36)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at kotlin.reflect.jvm.internal.ReflectProperties$LazyVal.invoke(ReflectProperties.java:62)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:31)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at kotlin.reflect.jvm.internal.KFunctionImpl.getCaller(Unknown Source:7)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at kotlin.reflect.jvm.ReflectJvmMapping.getJavaMethod(ReflectJvmMapping.kt:63)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at kotlin.reflect.jvm.KCallablesJvm.setAccessible(KCallablesJvm.kt:82)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at com.hjq.gson.factory.constructor.KotlinDataClassDefaultValueConstructor.construct(KotlinDataClassDefaultValueConstructor.kt:29)
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at com.hjq.gson.factory.constructor.l.construct(ReflectCreatorConstructor.java:29)
2024-04-09 19:18:54.733  6374-16662 BLASTBufferQueue        com.wepie.wespy                      D  [VRI[PartyHomeActivity]#15](f:0,a:1) acquireNextBufferLocked size=24x24 mFrameNumber=1 applyTransaction=true mTimestamp=108821324931038(auto) mPendingTransactions.size=0 graphicBufferId=27376121544767 transform=0
2024-04-09 19:18:54.733  6374-16483 System.err              com.wepie.wespy                      W  	at com.hjq.gson.factory.b.e.read(ReflectiveTypeAdapter.java:58)
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at com.hjq.gson.factory.c.c$1.a(ReflectiveTypeUtils.java:110)
2024-04-09 19:18:54.734  6374-16662 VRI[PartyHomeActivity]  com.wepie.wespy                      D  Received frameCommittedCallback lastAttemptedDrawFrameNum=1 didProduceBuffer=true syncBuffer=false
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at com.hjq.gson.factory.b.e.read(ReflectiveTypeAdapter.java:71)
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at com.hjq.gson.factory.c.c$1.a(ReflectiveTypeUtils.java:110)
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at com.hjq.gson.factory.b.e.read(ReflectiveTypeAdapter.java:71)
2024-04-09 19:18:54.734  6374-6374  VRI[PartyHomeActivity]  com.wepie.wespy                      D  draw finished.
2024-04-09 19:18:54.734  6374-6374  VRI[PartyHomeActivity]  com.wepie.wespy                      D  reportDrawFinished
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at com.google.gson.Gson.fromJson(Gson.java:1227)
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at com.google.gson.Gson.fromJson(Gson.java:1329)
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at com.google.gson.Gson.fromJson(Gson.java:1300)
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at com.three.http.callback.DataCallback.parseResponse(DataCallback.java:74)
2024-04-09 19:18:54.734  6374-6374  ViewRootImplExtImpl     com.wepie.wespy                      D  setMaxDequeuedBufferCount: 2
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at com.three.http.core.HttpUtil$3.onResponse(HttpUtil.java:288)
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174)
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
2024-04-09 19:18:54.734  6374-16483 System.err              com.wepie.wespy                      W  	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
2024-04-09 19:18:54.735  6374-16483 System.err              com.wepie.wespy                      W  	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
2024-04-09 19:18:54.735  6374-16483 System.err              com.wepie.wespy                      W  	at java.lang.Thread.run(Thread.java:1012)

提供截图或视频

No response

提供解决方案

No response

[Bug]:9.0升级9.2

框架版本【必填】

9.2

问题描述【必填】

当我调用接口时返回错误:
ApiResponse#data,后台返回的条目类型为:BEGIN_OBJECT

复现步骤【必填】

使用 Retrofit.Builder().addConverterFactory(GsonConverterFactory.create(GsonFactory.getSingletonGson()))

调用接口:

suspend fun login(@Body request: LoginRequest): ApiResponse<String>

后台返回值:

{
    "code" : 0,
    "data" : "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUz",
    "extra" : null,
    "message" : "success",
    "path" : null,
    "timestamp" : 1702881400175
}

ApiResponse实体类:

data class ApiResponse<T>(
    val code: Int?,
    val data: T?,
    val extra: Extra?,
    val message: String?,
    val path: String?,
    val timestamp: Any?,
    val version: String?,
) : BaseResponse<T>() {

    override fun isSuccess(): Boolean = code == 0

    override fun getResponseCode(): Int = code ?: -1

    override fun getResponseData(): T? = data

    override fun getResponseExtra(): Extra? = extra

    override fun getResponseMessage(): String? = message

    override fun getResponsePath(): String? = path

    override fun getResponseTimestamp(): Any? = timestamp

    override fun getResponseVersion(): String? = version
}
abstract class BaseResponse<T> {
    abstract fun isSuccess(): Boolean

    abstract fun getResponseCode(): Int

    abstract fun getResponseData(): T?

    abstract fun getResponseExtra(): Extra?

    abstract fun getResponseMessage(): String?

    abstract fun getResponsePath(): String?

    abstract fun getResponseTimestamp(): Any?

    abstract fun getResponseVersion(): String?
}
data class Extra(
    val errorMsg: String?
)

是否必现【必填】

项目 targetSdkVersion【必填】

33

出现问题的手机信息【必填】

小米mix2、逍遥模拟器(android 9版本)

出现问题的安卓版本【必填】

Android 9

问题信息的来源渠道【必填】

自己遇到的

是部分机型还是所有机型都会出现【必答】

目前仅测试小米mix2、逍遥模拟器(android 9版本)

框架最新的版本是否存在这个问题【必答】

框架文档是否提及了该问题【必答】

是否已经查阅框架文档但还未能解决的【必答】

issue 列表中是否有人曾提过类似的问题【必答】

是否已经搜索过了 issue 列表但还未能解决的【必答】

是否可以通过 Demo 来复现该问题【必答】

提供报错堆栈

No response

提供截图或视频

No response

提供解决方案

No response

[疑惑]:<init> argument 4 has type int, got null,

问题描述【必填】

data class SumInfo(
        var columnistCount: Int = 0,
        var courseCount: Int = 0
    ) 

需求场景需要支持默认值为0;解析的时候会有警告信息

java.lang.IllegalArgumentException: method com.dop.data.user.User$SumInfo.<init> argument 4 has type int, got null

警告来自下面的代码

 Object[] parameterValue = new Object[parameterLength];
                // 这个参数是标记位,用于判断有没有设置默认值进去,会进行 & 位运算进行判断
                // 这里设置成 Integer.MAX_VALUE,Integer.MAX_VALUE & 大于 0 的值,都会等于那个值
                // 这样就能每次都能走到设置默认值那里
                // Github 地址:https://github.com/getActivity/GsonFactory/issues/27
                parameterValue[parameterLength - 2] = Integer.MAX_VALUE;
                // 这个参数 DefaultConstructorMarker 类型,用于标记构造函数是 Kotlin 语法自动生成的
                parameterValue[parameterLength - 1] = null;

                for (int i = 0; i < parameterTypes.length - 2; i++) {
                    Class<?> parameterType = parameterTypes[i];
                    parameterValue[i] = getTypeDefaultValue(parameterType);
                }

                instance = (T) constructor.newInstance(parameterValue);

请问要怎么正确的处理默认值0的情况呢?

框架文档是否提及了该问题【必答】

是否已经查阅框架文档但还未能解决的【必答】

issue 列表中是否有人曾提过类似的问题【必答】

是否已经搜索过了 issue 列表但还未能解决的【必答】

请严格按照 issue 模板来提问题,否则一律不受理

最近发现有很多人给我提 issue 没有认真按照模板上面的来填写,导致了在排查问题的过程中浪费了作者许多不必要的时间和精力,所以请后面提 issue 的人务必严格遵守,否则我不会受理,直接关闭 issue。

[疑惑]:GsonFactory反序列化数据量大时速度有点慢

问题描述【必填】

我分别使用GsonFactory.getSingletonGson().fromJson(str,type)和Gson().fromJson(str,type)来解析文件大小为 300kb 的 json 字符串,前者耗时 700-800 毫秒,后者100 毫秒不到。是我使用的方式不对吗?还是因为框架为了适配做了很多处理的缘故。
版本 9.2

框架文档是否提及了该问题【必答】

是否已经查阅框架文档但还未能解决的【必答】

issue 列表中是否有人曾提过类似的问题【必答】

是否已经搜索过了 issue 列表但还未能解决的【必答】

大佬能不能增加,Bean里设定了字段Json返回空的时候赋值个默认值,比如String字段是null的时候转换成空字符串"",int换0

Question Description [Required]

或者说大佬你已经做了我没发现用法?
我测试好像目前都是遇到null字段都会跳过解析
我的json:

{"code":1,"msg":"","data":{"order":{"id":1863,"number":"2024070618060434152","customer_id":null,"produce_cate_code":10000,"product_id":2295,"state":4,"pay_status":null,"store_name":"测试组织三","customer_name":null,"product_name":"测试123456789","linkman":null,"mobile":null,"contacts":null,"contacts_mobile":null,"run":null,"order_type":1,"agency_name":"测试三组","agency_admin_name":null,"agency_owner_name":"测试三组","agency_owner_admin_name":"测试管理员","money":"25.00","start_time":"2024-07-06","end_time":"2026-07-05","create_time":"2024-07-06","address":"测试11111111111111111111111111","unit":"月","peer_price":"0.10","order_state_name":"作废","pay_state_name":"待处理"},"auth":[]}}

Is the issue mentioned in the framework documentation? [Required]

No

Did you consult the framework documentation but couldn't find a solution? [Required]

Yes

Has a similar issue been reported in the issue list? [Required]

No

Have you searched the issue list but couldn't find a solution? [Required]

Yes

BigDecimalTypeAdapter 有BUG

String result = in.nextString();
if (result == null || "".equals(result)) {
return new BigDecimal(0);
}
return new BigDecimal(in.nextString());

return new BigDecimal(in.nextString());
应改为:
return new BigDecimal(result);

8.0版本 jitpack无法引用依赖

框架版本【必填】

8.0

问题描述【必填】

https://jitpack.io/com/github/getActivity/GsonFactory/8.0/build.log
3月25的打包失败,无法引用依赖

复现步骤【必填】

直接依赖8.0版本错误

是否必现【必填】

项目 targetSdkVersion【必填】

33

出现问题的手机信息【必填】

出现问题的安卓版本【必填】

问题信息的来源渠道【必填】

自己遇到的

是部分机型还是所有机型都会出现【必答】

所有

框架最新的版本是否存在这个问题【必答】

框架文档是否提及了该问题【必答】

是否已经查阅框架文档但还未能解决的【必答】

issue 列表中是否有人曾提过类似的问题【必答】

是否已经搜索过了 issue 列表但还未能解决的【必答】

是否可以通过 Demo 来复现该问题【必答】

提供报错堆栈

No response

提供截图或视频

No response

提供解决方案

No response

json名字中带特殊符表情比如😁(unicode)的数据是否有容错处理

【警告:请务必按照 issue 模板填写,不要抱有侥幸心理,一旦发现 issue 没有按照模板认真填写,一律直接关闭】

问题描述

  • json名字中带特殊符表情比如😁(unicode)的数据是否有容错处理

请回答

  • issue 是否有人曾提过类似的问题?【必答】否

  • 框架文档是否有提及到此问题?【必答】:否

打包成正式版解析有个BUG

问题描述:同样的代码,在测试版一切正常,但是 打包成正式版之后 解析就出问题了。我用的技术中台的模板项目,把相关的网络请求代码加进去测试的 代码和测试结果如下
public class HttpList2Data extends HttpData<HttpList2Data.ListBean> {

public static class ListBean<T> {

    /** 当前页码 */
    private int pageIndex;
    /** 页大小 */
    private int pageSize;
    /** 总数量 */
    private int totalNumber;
    /** 数据 */
    private List<T> rows;

    public List<T> getRows() {
        return rows;
    }

    /**
     * 判断是否是最后一页
     */
    public boolean isLastPage() {
        return Math.ceil((float) totalNumber / pageSize) <= pageIndex;
    }

    public int getTotalNumber() {
        return totalNumber;
    }

    public int getPageIndex() {
        return pageIndex;
    }

    public int getPageSize() {
        return pageSize;
    }

    @Override
    public @NotNull String toString() {
        return "ListBean{" +
                "pageIndex=" + pageIndex +
                ", pageSize=" + pageSize +
                ", totalNumber=" + totalNumber +
                ", rows=" + rows +
                '}';
    }
}

}
image
测试结果:
2021-10-29 11:11:23.587 18625-18773/com.hjq.demo I/EasyHttp:
{
"code" : "0",
"data" : {
"total" : 1,
"rows" : [
{
"address" : "",
"air_north_time" : "",
"condition" : "么有",
"create_date" : 1635316395600,
"create_user" : "admin",
"direction" : "",
"dynamic" : "3",
"dynamic_img" : "/upload//fjkcjs/202110/fjkcjs_1635316393452.jpeg",
"dynamic_time" : 1635316320609,
"enterprise_id" : "fjkcjs",
"id" : "02dbba90ebe848ccadabb1aed2b0b52f",
"latitude" : "0.006",
"longitude" : "0.0065",
"now_port" : "",
"remark" : "",
"ship_date_id" : "b27ec0bdaf3c4c11a661af88a337fa2a",
"ship_position" : "",
"update_date" : "",
"update_user" : ""
}
]
},"message" : "成功"
}
com.hjq.demo D/(:119): text==={"code":"0","data":{"total":1,"rows":[{"address":"","air_north_time":"","condition":"么有","create_date":1635316395600,"create_user":"admin","direction":"","dynamic":"3","dynamic_img":"/upload//fjkcjs/202110/fjkcjs_1635316393452.jpeg","dynamic_time":1635316320609,"enterprise_id":"fjkcjs","id":"02dbba90ebe848ccadabb1aed2b0b52f","latitude":"0.006","longitude":"0.0065","now_port":"","remark":"","ship_date_id":"b27ec0bdaf3c4c11a661af88a337fa2a","ship_position":"","update_date":"","update_user":""}]},"message":"成功"}

com.hjq.demo D/(:122): result===HttpData{code=0, msg='null', data=ListBean{pageIndex=0, pageSize=0, totalNumber=0, rows=[ShipDynamicListBean{air_north_time=null, create_date=null, create_user='null', condition='null', remark='null', direction='null', dynamic='null', dynamicName='null', dynamic_time=null, enterprise_id='null', id='null', now_port='null', ship_date_id='null', ship_position='null', update_date=null, update_user='null', dynamic_img='null'}]}}

从结果可以看出定位在这段代码
try {
result = GsonFactory.getSingletonGson().fromJson(text, type);
Timber.d("result===%s",result);
} catch (JsonSyntaxException e) {
// 返回结果读取异常
throw new DataException(mApplication.getString(R.string.http_data_explain_error), e);
}
我最奇怪的是 debug版运行 我在这里打断点查看 一点问题都没有 但是一打包成正式的 就解析不出来了 而且还没报错 找这个bug找的我脑瓜子嗡嗡的 说的有点啰嗦了 希望大佬能看下

[Bug]:升级到 9.3 直接无法解析

框架版本【必填】

v9.3

问题描述【必填】

从v9.0升级v9.3直接无法解析了 炸了
image

复现步骤【必填】

所有接口都解析不了 9.0正常

是否必现【必填】

项目 targetSdkVersion【必填】

23

出现问题的手机信息【必填】

小米

出现问题的安卓版本【必填】

13

问题信息的来源渠道【必填】

No response

是部分机型还是所有机型都会出现【必答】

跟机型没关系

框架最新的版本是否存在这个问题【必答】

未选择

框架文档是否提及了该问题【必答】

未选择

是否已经查阅框架文档但还未能解决的【必答】

未选择

issue 列表中是否有人曾提过类似的问题【必答】

未选择

是否已经搜索过了 issue 列表但还未能解决的【必答】

未选择

是否可以通过 Demo 来复现该问题【必答】

未选择

提供报错堆栈

![image](https://github.com/getActivity/GsonFactory/assets/41047773/b4e30b58-0dfc-4268-bd31-ebe4ee8ce4a9)

提供截图或视频

image

提供解决方案

image

请问一下这样处理可以吗?

addConverterFactory(GsonConverterFactory.create(GsonBuilder().create())),GsonBuilder().create() 这个更换成类库里的Gson实例,可以处理容错么?比如int的字段,但是后台返回的小数!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.