升级Gradle插件后ProGuard与GSON配合引发解析异常问题
问题分析
升级Gradle插件到7.4.2后,ProGuard/R8的混淆策略更激进,你添加的-keep class com.yego.AppModal.DriverBalanceStat仅保留了类名,类内的字段名仍会被混淆成a、b等短标识。GSON默认依赖字段名进行序列化和反序列化,导致存储的JSON键名与反序列化时期望的字段名不匹配,最终抛出类型不匹配的IllegalStateException。
解决方案
1. 修正ProGuard/R8规则
在你的proguard-rules.pro文件中添加以下规则,确保保留DriverBalanceStat类的所有字段和构造方法:
# 保留DriverBalanceStat类的字段和构造方法,防止混淆 -keep class com.yego.AppModal.DriverBalanceStat { <fields>; <init>(...); } # 通用GSON混淆规则(可选,若有其他GSON序列化类也适用) -keepattributes Signature -keepattributes *Annotation* -keep class com.google.gson.** { *; }
<fields>:保留类的所有字段,避免字段名被混淆<init>(...):保留所有构造方法,确保GSON能通过反射实例化对象
2. 可选:添加@SerializedName注解(更稳妥的方案)
为DriverBalanceStat类的字段添加@SerializedName注解,强制指定JSON序列化的键名。这样即使字段名被混淆,GSON仍会使用注解中定义的键名,彻底避免字段名混淆带来的兼容性问题:
import com.google.gson.annotations.SerializedName; public class DriverBalanceStat { @SerializedName("Balance") public Double Balance; @SerializedName("PendingDays") public Integer PendingDays; @SerializedName("IsMeterBlocked") public boolean IsMeterBlocked; @SerializedName("BalanceDate") public Long BalanceDate; @SerializedName("CashbackAmount") public double CashbackAmount; @SerializedName("IsAllowCashTrip") public Boolean IsAllowCashTrip; @SerializedName("IsAllowCashlessTrip") public Boolean IsAllowCashlessTrip; // 构造方法保持不变 public DriverBalanceStat(Double balance, Integer pendingDays, boolean isMeterBlocked, Long balanceDate, Double cashbackAmount, Boolean isAllowCashTrip, Boolean isAllowCashlessTrip) { this.Balance = balance; this.PendingDays = pendingDays; this.IsMeterBlocked = isMeterBlocked; this.BalanceDate = balanceDate; this.CashbackAmount = cashbackAmount; this.IsAllowCashTrip = isAllowCashTrip; this.IsAllowCashlessTrip = isAllowCashlessTrip; } }
3. 验证修复效果
构建Release版本后,检查SharedPreferences中存储的JSON内容,确认键名已恢复为原始字段名(如Balance、PendingDays等),此时调用GetAppObjectByKey方法即可正常反序列化对象。
内容的提问来源于stack exchange,提问作者Rajeev Kumar
相关产品推荐
相关产品推荐

