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

我正在编写一个Android应用程序需要使用GSON来反序列化JSONstring:

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

所以我创build了两个类:

 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(); } 

是什么让我感到困惑的是,当我debugging应用程序,它运行良好,输出“notNULL”。我可以看到对象的每个属性已被正确反序列化。 然而,当我从Android Studio生成发布的apk并在手机上运行apk时,它输出“isNULL”,JSONparsing失败!

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

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') } 

Solutions Collecting From Web of "Gson反序列化发布的apk中的空指针"

您在release版本types中启用了ProGuard – minifyEnabled true 。 它通过更改类/variables名称来模糊代码。

你应该注释你的类属性,所以Gson知道要寻找什么:

 public class ReturnData { @SerializedName("reply_code") public String reply_code; @SerializedName("userinfo") public userinfo userinfo; } public class userinfo { @SerializedName("username") public String username; @SerializedName("userip") public String userip; } 

这样Gson将不会查看属性的名称,但会查看@SerializedName注释。

您可以使用@SerializedName N提到的@SerializedName,也可以通过使用Gson类到proguard-rules.pro

 -keep class com.packageName.yourGsonClassName 

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

  • 当你编写你的代码时,你可以把所有的Gson类放到一个文件夹中,并使用下面的代码保留所有的Gson类的模糊处理,从而节省了大量的编码:

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

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

将您的json代码更改为以下内容..

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

现在尝试parsingjson …