Gson deserializa puntero nulo en apk liberado
Estoy escribiendo una aplicación para Android que necesito usar gson para deserializar la cadena json:
{ "reply_code": 001, "userinfo": { "username": "002", "userip": 003 } }
Así que creo dos clases:
- Google signin no funciona con producción apk en playstore. (Release apk en playstore)
- ¿Cómo hacer que la aplicación de Android configure automáticamente los valores w / debug vs. release?
- Apk sólo se ejecuta en modo de depuración. Apk comenzó con "Ejecutar" en Eclipse se detiene en puntos de interrupción
- Desactivar LogCat Salida COMPLETAMENTE en la versión de Android app?
- Diferencia entre depug y release apks
public class ReturnData { public String reply_code; public userinfo userinfo; } public class userinfo { public String username; public String userip; }
Finalmente, mi código Java en MainActivity.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(); }
Lo que me hizo confundir es, cuando depuro la aplicación, se ejecutó bien y la salida "notNULL". Puedo ver cada atribución del objeto ha sido deserialized correctamente. Sin embargo, cuando he generado apk liberado de Android Studio y ejecutar apk en el teléfono, la salida "isNULL", la resolución json falló!
¿Quién puede decirme qué sucedió?
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') }
- Versión de lanzamiento de Android y "Esperando depurador"
- Google Maps no se muestra en apk firmado
- ¿Cómo puedo crear un certificado para mi Android Market APK?
- ¿Por qué se necesita un apk no alineado?
- Android Studio: ejecuta / depura la versión de lanzamiento de la aplicación
- Crear el modo de publicación de la aplicación para Android
Tiene ProGuard habilitado en su tipo de versión de release
: minifyEnabled true
. Obfusca el código cambiando los nombres de clase / variable.
Debería anotar las propiedades de su clase, por lo que Gson sabe qué buscar:
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; }
De esta manera Gson no mirará los nombres de las propiedades, sino que mirará la anotación @SerializedName
.
Puede utilizar @SerializedName
como se menciona por @Egor N o puede agregar las clases de Gson a proguard-rules.pro
mediante
-keep class com.packageName.yourGsonClassName
Este último tiene las siguientes ventajas sobre el primero:
-
Al escribir su código puede poner toda su clase de Gson en una carpeta y mantener todos ellos de ofuscación con lo siguiente, lo que ahorra una gran cantidad de codificación:
-keep class com.packageName.gsonFolder.** { *; }
-
La adición de
@SerializedName
a cada campo en las clases de Gson no sólo requiere mucho tiempo, especialmente en grandes proyectos con muchos archivos Gson, sino que también aumenta la posibilidad de errores al introducir el código, si el argumento en el@SerializedName
es diferente del nombre del campo. -
Si se utilizan otros métodos, como los métodos getter o setter en la clase Gson, también pueden obfuscated. No utilizar
@SerializedName
para estos métodos provoca fallo en tiempo de ejecución debido a conflicto en nombres.
Cambie su código json a lo siguiente ..
{ "reply_code": "001", "userinfo": [ { "username": "002" }, { "userip": "003" } ] }
Ahora trate de analizar el json …