You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

启用混淆时Kotlin数据类的Gson反序列化错误

Android多模块混淆后Gson解析泛型数据类报错

问题详情

在Android多模块项目的网络模块中,使用Kotlin泛型数据类作为Retrofit的数据传输对象:

data class GenericPaginationResponse<T>(
    @SerializedName("data")
    val data: List<T>,
    @SerializedName("pagination")
    val pagination: PaginationResponse
)

开启代码混淆后,应用运行时抛出错误:

Unable to invoke no-args constructor for class com.lelestacia.network.model.GenericPaginationResponse. Registering an InstanceCreator with Gson for this type may fix this problem.

当前ProGuard配置如下:

# If you keep the line number information, uncomment this to
# hide the original source file name.
-renamesourcefileattribute SourceFile

 # Keep generic signature of Call, Response (R8 full mode strips signatures from non-kept items).
 -keep,allowobfuscation,allowshrinking interface retrofit2.Call
 -keep,allowobfuscation,allowshrinking class retrofit2.Response

 # With R8 full mode generic signatures are stripped for classes that are not
 # kept. Suspend functions are wrapped in continuations where the type argument
 # is used.
 -keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation

 -if class * {
   @com.google.gson.annotations.SerializedName <fields>;
 }

 -keep class <1> {
   <init>();
 }

解决办法

核心原因

现有ProGuard规则未正确保留泛型数据类的无参构造器和泛型签名,R8混淆时会移除这些关键信息,导致Gson无法通过反射实例化泛型类、识别泛型类型。

修改ProGuard配置

添加以下规则到混淆文件中:

  1. 针对性保留目标泛型类
# 保留GenericPaginationResponse的构造器、字段和泛型签名
-keep class com.lelestacia.network.model.GenericPaginationResponse {
    <init>();
    <fields>;
}

# 同时保留关联的PaginationResponse类
-keep class com.lelestacia.network.model.PaginationResponse {
    <init>();
    <fields>;
}

# 必须保留泛型签名属性,否则Gson无法识别泛型类型
-keepattributes Signature
  1. 批量处理网络模块所有DTO(可选)
    如果网络模块存在多个泛型或普通数据类,可使用通配符统一处理:
# 保留网络模块所有带SerializedName注解的数据类
-keep,allowobfuscation class com.lelestacia.network.model.** {
    @com.google.gson.annotations.SerializedName <fields>;
    <init>();
}

# 保留泛型签名
-keepattributes Signature

说明

  • -keepattributes Signature 是关键:阻止R8移除类的泛型签名信息,Gson依赖该信息解析GenericPaginationResponse<T>中的泛型参数T。
  • 显式保留无参构造器:Kotlin数据类默认生成无参构造器,但混淆时可能被优化移除,必须明确保留才能让Gson通过反射实例化对象。

内容的提问来源于stack exchange,提问作者lelestacia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 04:32:45