2015-05-02 9 views
9

Sto scrivendo un app Android bisogno utilizzando GSON per deserializzare la stringa JSON:GSON deserializzare puntatore nullo nel rilasciato apk

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

quindi creare due classi:

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

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

infine, il mio Java codice 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(); 
} 

Cosa mi ha fatto confuso è, quando il debug l'applicazione, ha funzionato bene e di uscita "notnull" ca .I n vedere che ogni attribuzione dell'oggetto è stata deserializzata correttamente. Tuttavia, quando ho generato apk rilasciato da Android Studio ed eseguito apk sul telefono, emette "isNULL", la risoluzione json non è riuscita!

Chi può dirmi cosa è successo ?!

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

mostra file prog. –

+0

@No Nome vuoi dire build.gradle? Ho caricato ora. – padeoe

+0

no show 'proguard-android.txt 'file –

risposta

21

Hai ProGuard abilitato nel tipo di build release - minifyEnabled true. Oscura il codice cambiando i nomi di classi/variabili.

Si dovrebbe annotare le proprietà di classe, in modo da GSON sa cosa cercare:

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

In questo modo GSON non guarderà i nomi delle proprietà, ma esaminerà @SerializedName annotazione.

+0

Grande! Funziona! Grazie – padeoe

+0

Questa risposta ha richiesto WAAAAY a lungo per trovare. Ben fatto @Egor N. – Silmarilos

+0

Grazie mille, molto !!!! –

-1

modificare il codice JSON al seguente ..

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

Ora provate a analizzare il JSON ...

10

È possibile utilizzare @SerializedName come detto da @Egor N o si può aggiungere le classi GSON al proguard-rules.pro utilizzando

-keep class com.packageName.yourGsonClassName 

Quest'ultimo ha i seguenti vantaggi rispetto l'ex:

  • quando scrivi il tuo codice puoi mettere tutta la tua classe Gson in una cartella e tenerne tutte le offuscate usando il seguente, che risparmia molto codice:

    -keep class com.packageName.gsonFolder.** { *; } 
    
  • Aggiunta @SerializedName ad ogni campo nelle classi GSON non è solo in termini di tempo soprattutto in progetti di grandi dimensioni con un sacco di file GSON ma aumenta anche la possibilità di errori che entrano nel codice, se l'argomento in @SerializedName è diverso da quello nome del campo.

  • Se altri metodi, come metodi getter o setter vengono utilizzati nella classe Gson, possono anche essere offuscati. Non utilizzare @SerializedName per questi metodi causa crash in fase di esecuzione a causa di conflitti nei nomi.

+0

Ottimo punto. Grazie. –

+0

Per me, funziona dopo aver aggiunto ulteriori informazioni ** campi privati ​​** come questo -keep class com.packageName.yourGsonClassName { private ; } –