You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android开启minifyEnabled=true后,Gson转换JSON字符串为自定义对象失败的原因及解决方法

解决Gson在minifyEnabled=true时无法映射JSON到自定义对象的问题

嗨,我来帮你搞定这个困扰你的问题!

问题原因

当你开启minifyEnabled=true后,Android的代码混淆工具(现在默认是R8,早期是ProGuard)会对自定义类(比如MyObjectModel)做压缩优化——它会把类里有意义的属性名(比如contentText)改成ab这类毫无意义的短名称,以此减小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

火山引擎 最新活动