2
votes

Problème d'analyse de Gson avec la version finale - une chaîne incorrecte est renvoyée

Salut j'ai un problème avec la bibliothèque Gson dans une version finale.

En pratique, dans la version commerciale de mon application, en utilisant la new Gson().toJson(obj) , une chaîne incorrecte est renvoyée.

Il manque un champ de mon objet dans la chaîne retournée. Est-il possible que la version finale nécessite des options manquantes?

Voici quelques informations utiles:

  • L' obj est une instance de ArrayList<MyClass>
  • J'utilise l' implementation 'com.google.code.gson:gson:2.8.5'
  • J'utilise Android Studio 3.5.1

MyClass est construit comme ceci:

[ 
   { 
      "a":"a",
      "b":"b",
      "c":"c",
      "d":"d",
   }
]

Exemple:

[ 
   { 
      "b":"b",
      "c":"c",
      "d":"d",
   }
]

Sortie courant:

MyClass example = new MyClass("a","b","c","d");

ArrayList<MyClass> listExample = new ArrayList<MyClass>();
listExample.add(example);

String strObj = new Gson().toJson(listExample);

Production attendue

public class MyClass{

    @SerializedName("a")
    private String a;

    @SerializedName("b")
    private Integer b;

    @SerializedName("c")
    private String c;

    @SerializedName("d")
    private String d;

    public String getA() {
        return a;
    }

    public void setA(String a) {
        this.a = a;
    }

    ...

}

Pour reproduire l'erreur, suivez simplement le github: https://github.com/Ciardini/error02


2 commentaires

Pouvez-vous montrer l'ensemble de MyClass avec toutes les méthodes et tous les constructeurs?


@ MichałZiober Il n'y a pas grand chose à faire, MyClass a deux constructeurs l'un vide et l'autre avec tous les champs. Comme l'exemple, la classe a toutes les méthodes get et set, je préfère ne pas partager la classe car elle contient plus de 50 champs. Aujourd'hui, je vais essayer de recréer un petit échantillon avec l'erreur et de le publier sur github.


4 Réponses :


0
votes

Vous devez @Expose instend de @SerializedName

@Expose
public String a;


1 commentaires

Comme ça @SerializedName("a") @Expose private Integer a; ou @Expose private Integer a; ne fonctionne pas.



1
votes

Apparemment, la toString() à l'intérieur de la classe analysée est nécessaire pour faire fonctionner la bibliothèque Gson.

Je ne sais pas pourquoi mais si vous le savez, n'hésitez pas à répondre!

L'ajout de la toString() est une petite astuce pour ajouter des informations à la version finale. Vous devez suivre la bonne façon de le faire et ajouter des règles pro-guard.

@Override
public String toString() {
    return "MyClass{" +
            "a='" + a + '\'' +
            ", b='" + b + '\'' +
            ", c='" + c + '\'' +
            ", d='" + d + '\'' +
            '}';
}


0 commentaires

2
votes

Dans la version version compilateur Android, réduisez et optimisez le code [voir la documentation Android] . R8 supprime certaines informations apparemment inutiles, qui sont nécessaires à Gson pour sérialiser correctement les objets. Pour empêcher R8 de supprimer ces informations, vous devez ajouter le code suivant au fichier proguard-rules.pro:

-keep class com.giacomociardini.error02.entities.** { <fields>; }

Pour d'autres détails, vous pouvez vous référer à cet exemple sur le dépôt officiel Gson GitHub .


1 commentaires

Fonctionne réellement! Merci beaucoup, j'ai supposé qu'Android réduisait la dimension du fichier, mais je n'avais aucune idée qu'il existait des règles pour définir ce qui est et ce qui ne l'est pas.



0
votes

J'ai eu ce problème dans les classes internes de la classe Model.java, donc j'ai fait cela avec le fichier proguard.pro de ce projet, les classes internes sont définies avec '$' dans proguard donc,

-keep class path_to_models.Models$MyClass { <fields>; }

Dans Android Studio 3.4, R8 est utilisé par défaut pour tous les projets par défaut, donc si vous devez passer à proguard, alors:

android.enableR8 = false dans gradle.properties; ou useProguard = true dans votre build.gradle.


0 commentaires