Gson在发布的apk中反序列化空指针

时间:2015-05-02 11:21:48

标签: android json debugging gson release

我正在编写Android应用,需要使用gson反序列化json字符串:

{
    "reply_code": 001,
    "userinfo": {
        "username": "002",
        "userip": 003
    }
}

所以我创建了两个类:

public class ReturnData {
    public String reply_code;
    public userinfo userinfo;
}

public class userinfo {
    public String username;
    public String userip;
}

最后,我在MainActivity.java中的Java代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Context context= MainActivity.this;

    //Test JSON
    String JSON="{\"reply_code\": 001,\"userinfo\": {\"username\": \"002\",\"userip\": 003}}";
    Gson gson = new Gson();
    ReturnData returnData=gson.fromJson(JSON,ReturnData.class);

    if(returnData.reply_code==null)
        Toast.makeText(context,"isNULL",Toast.LENGTH_SHORT).show();
    else
        Toast.makeText(context,"notNULL",Toast.LENGTH_SHORT).show();
}

令我困惑的是,当我调试应用程序时,它运行良好并输出" notNULL"。我可以看到对象的每个属性都已正确反序列化。 但是,当我从Android Studio生成发布的apk并在手机上运行apk时,它输出" isNULL",json分辨率失败!

谁能告诉我发生了什么?!

PS:的build.gradle:

apply plugin: 'com.android.application'
android {
compileSdkVersion 19
buildToolsVersion "19.1"

defaultConfig {
    applicationId "com.padeoe.autoconnect"
    minSdkVersion 14
    targetSdkVersion 21
    versionCode 1
    versionName "2.1.4"
}
buildTypes {
    release {
        minifyEnabled true
        shrinkResources true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_7
    targetCompatibility JavaVersion.VERSION_1_7
}
}

dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile files('src/gson-2.3.1.jar')
}

1 个答案:

答案 0 :(得分:15)

您可以使用@Egor N提到的@SerializedName,也可以使用

将Gson类添加到proguard-rules.pro
-keep class com.packageName.yourGsonClassName

后者比前者具有以下优点:

  • 在编写代码时,您可以将所有Gson类放在一个文件夹中,并使用以下代码保持所有这些不被混淆,这样可以节省大量代码:

    -keep class com.packageName.gsonFolder.** { *; }
    
  • 向Gson类中的每个字段添加@SerializedName不仅耗时,特别是在具有大量Gson文件的大型项目中,而且如果{中的参数}也增加了输入代码的错误的可能性{1}}与字段名称不同。

  • 如果在Gson类中使用任何其他方法(如getter或setter方法),它们也可能会被混淆。由于名称冲突,不使用@SerializedName这些方法会导致运行时崩溃。