Android开启minifyEnabled=true后,Gson转换JSON字符串为自定义对象失败的原因及解决方法
解决Gson在minifyEnabled=true时无法映射JSON到自定义对象的问题
嗨,我来帮你搞定这个困扰你的问题!
问题原因
当你开启minifyEnabled=true后,Android的代码混淆工具(现在默认是R8,早期是ProGuard)会对自定义类(比如MyObjectModel)做压缩优化——它会把类里有意义的属性名(比如contentText)改成a、b这类毫无意义的短名称,以此减小APK体积、保护代码。
但Gson是靠属性名和JSON字段名的精确匹配来完成映射的,混淆后属性名变了,Gson找不到对应的JSON字段,自然就会把所有属性设为空,最终导致你遇到空指针异常。
另外提一句,你代码里先把JSON转成JSONObject再转成String的步骤其实完全没必要,直接用Gson解析原始的result字符串就行,多余步骤反而可能引入额外问题。
解决方法
这里给你两种最常用的解决方案,按需选择:
方案一:使用@SerializedName注解(推荐)
给MyObjectModel的每个属性添加@SerializedName注解,明确指定它对应的JSON字段名。这样不管混淆工具把属性名改成什么,Gson都能通过注解找到正确的JSON字段:
import com.google.gson.annotations.SerializedName; public class MyObjectModel { // 指定JSON里的字段名为"contentText",和属性名无关 @SerializedName("contentText") private String contentText; // 其他属性同理 @SerializedName("otherField") private String otherField; // getter和setter方法 public String getContentText() { return contentText; } }
方案二:在混淆规则中保留自定义类
如果你不想给每个属性加注解,可以在proguard-rules.pro文件中添加规则,让混淆工具不对你的MyObjectModel类(或者整个模型类包)进行混淆:
# 保留指定类的所有属性和方法,不进行混淆 -keep class com.yourpackage.MyObjectModel { *; } # 如果你的模型类都在同一个包下,可以用通配符批量保留 -keep class com.yourpackage.models.** { *; }
注意替换com.yourpackage为你实际的包名。这种方法的缺点是会让整个类不被混淆,可能会稍微增大APK体积,也会降低代码的保密性。
额外优化建议
把你原来的代码简化一下,直接用Gson解析原始的API返回字符串,去掉多余的JSONObject转换步骤:
Gson gson = new Gson(); MyObjectModel mobj = gson.fromJson(result, MyObjectModel.class); String t = mobj.getContentText();
内容的提问来源于stack exchange,提问作者Davood




