getActivity / GsonFactory

Gson 解析容错框架,愿从此再无 Json 解析报错
Apache License 2.0
667 stars 66 forks source link

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

Closed Summer-Android closed 8 months ago

Summer-Android commented 8 months ago

框架版本【必填】

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

getActivity commented 8 months ago

小伙子,提供 GroupChatByPageResult 类源码,以及网络请求的代码。

Summer-Android commented 8 months ago

小伙子,提供GroupChatByPageResult类源码,以及网络请求的代码。

data class GroupChatByPageResult(
    val datas: List<Data>,
    val empty: Boolean,
    val total: Int
) {
    data class Data(
        val groupId: String,
        val groupImg: String,
        val groupName: String,
        val groupNum: Int,
        var selectState: Boolean = false,
    )
}
    @POST("im-business/groupChat/groupChatByPage")
    suspend fun groupChatByPage(@Body request: GroupChatByPageRequest): ApiResponse<GroupChatByPageResult>
getActivity commented 8 months ago
image
getActivity commented 8 months ago

小伙子,datas 这个字段被你定义成了非空,但是又没有给它赋值导致的问题。

getActivity commented 8 months ago

你尝试把 datas 定义成可空的,又或者在字段上面赋一下默认值试试看?

Summer-Android commented 8 months ago

我上面json中datas是有值的

getActivity commented 8 months ago

但是 Gson 的解析方式是先反射创建,再解析 Json 进行赋值,你在反射创建那一步就通过不了。

Summer-Android commented 8 months ago

但是 Gson 的解析方式是先反射创建,再解析 Json 进行赋值,你在反射创建那一步就通过不了。

为什么9.0的版本没有问题

getActivity commented 8 months ago

@Summer-Android 因为从 9.0 版本后,反射创建 kotlin data class 类的方式被修改了,具体你可以代码提交记录,准确来讲 9.0 的代码存在一些 Bug,所以我修改了 kotlin data class 类的反射创建方式。

getActivity commented 8 months ago

https://github.com/getActivity/GsonFactory/releases/tag/9.2

getActivity commented 8 months ago
image
Summer-Android commented 8 months ago

尝试你把datas定义成可空的,又或者在上面的字段赋一下默认值试试看?

定义为可空类型是没有问题了,但是假设后台返回的结果一定是有数据的,我不想定义为可空类型,因为定义为可空我就要去做判空处理

Xxj-star commented 8 months ago

9.0升级9.3 就没法使用了 我不想定义为可空类型,因为定义为可空我就要去做判空处理

getActivity commented 8 months ago

尝试你把datas定义成可空的,又或者在上面的字段赋一下默认值试试看?

定义为可空类型是没有问题了,但是假设后台返回的结果一定是有数据的,我不想定义为可空类型,因为定义为可空我就要去做判空处理

小伙子,你这种写法是有问题的,你既然不想让 datas 为空,那么应该给 datas 赋一个默认值,但是你又没有那么做,归根结底是编译器没有限定 kotlin data class 非空字段一定要赋值的问题,当然这个是我认为最理想的方法,但是 kotlin 并没有这样限定,所以留下了这么一个坑,前期你先这样做,后面我再想想能不能通过框架内部解决这个问题(目前暂时没有想到好的解决方案,如果你有的话,欢迎提供给我)

getActivity commented 8 months ago

GsonFactory-9.32.aar.zip

getActivity commented 8 months ago

小伙子,针对这个问题,我在框架内部进行了处理,当你在 data class 类上面定义了不为空的字段,但是又没有赋值,那么框架会自动赋予一个默认值,不同类型的字段默认值也不相同,你可以参考一下

getActivity commented 8 months ago

GsonFactory-9.32.aar.zip

@Summer-Android 小伙子,有空可以测试一下,如果有问题请及时反馈给我。

Xxj-star commented 8 months ago

//这种后台data没有数据的时候 返回一个[]空数组 为什么不能解析了 报错了? image

getActivity commented 8 months ago

@xuxinjiang 小伙子,你这个属于第三方库依赖的问题,你加一下这个的依赖应该就没有问题了

dependencies {
    // Kotlin 反射库:用于反射 Kotlin data class 类对象
    implementation 'org.jetbrains.kotlin:kotlin-reflect:1.5.10'
}
getActivity commented 8 months ago

@Summer-Android @xuxinjiang 小伙子们,远程依赖已更新,更新到 9.5 版本即可

image
getActivity commented 8 months ago
image

@xuxinjiang 还有跟这位小伙子说声抱歉,没有及时更新远程依赖,但是我有自己考虑,没有及时更新远程依赖的原因如下:

  1. 这个问题不是非常严重(可以暂时通过修改代码的写法来解决问题)
  2. 尽管每次代码修改后我做足了自测,但是无法 100% 保证,需要有人验证
  3. 框架的灰度机制,需要有人来做一个阶段的小白鼠,如果不那么做,直接贸然发布远程依赖,一旦出现问题,会影响更多的人