AssertionError dans Gson EnumTypeAdapter lors de l'utilisation de Proguard de la Dissimulation de l'
Mon projet met en œuvre une TypeAdapter
dans Gson
au cours de la sérialisation/désérialisation pour la préservation de l'objet du polymorphisme de l'état. De toute façon, le projet fonctionne bien, durant le développement, les tests, mais quand il est sorti avec proguard de la dissimulation de l' et testé, c'est juste se bloque.
03-21 10:06:53.632: E/AndroidRuntime(12441): FATAL EXCEPTION: main
03-21 10:06:53.632: E/AndroidRuntime(12441): java.lang.AssertionError
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.internal.bind.TypeAdapters$EnumTypeAdapter.<init>(SourceFile:724)
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.internal.bind.TypeAdapters$26.create(SourceFile:753)
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.Gson.getAdapter(SourceFile:353)
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(SourceFile:82)
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(SourceFile:81)
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(SourceFile:118)
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(SourceFile:72)
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.Gson.getAdapter(SourceFile:353)
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.Gson.toJson(SourceFile:578)
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.Gson.toJsonTree(SourceFile:479)
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.Gson.toJsonTree(SourceFile:458)
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.Gson$3.serialize(SourceFile:137)
Mon Gson spécifiques proguard configuration est la suivante:
##---------------Begin: proguard configuration for Gson ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON @Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
#This is extra - added by me to exclude gson obfuscation
-keep class com.google.gson.** { *; }
##---------------End: proguard configuration for Gson ----------
La TypeAdapter que j'utilise est:
public final class GsonWorkshiftAdapter implements JsonSerializer<IWorkshift>, JsonDeserializer<IWorkshift> {
private static final String CLASSNAME = "CLASSNAME";
private static final String INSTANCE = "INSTANCE";
@Override
public JsonElement serialize(IWorkshift src, Type typeOfSrc, JsonSerializationContext context) {
String className = src.getClass().getCanonicalName();
JsonElement elem = context.serialize(src);
JsonObject retValue = new JsonObject();
retValue.addProperty(CLASSNAME, className);
retValue.add(INSTANCE, elem);
return retValue;
}
@Override
public IWorkshift deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
JsonPrimitive prim = (JsonPrimitive) jsonObject.get(CLASSNAME);
String className = prim.getAsString();
Class<?> klass = null;
try { klass = Class.forName(className); }
catch (ClassNotFoundException e) { throw new JsonParseException(e.getMessage()); }
return context.deserialize(jsonObject.get(INSTANCE), klass);
}
}
J'ai fait beaucoup de recherche sur cette erreur spécifique à Gson, mais ne pouvais pas trouver toute réponse utile. Cependant, j'ai trouvé une autre question de la même question.
Toute aide de la part du développeur de la communauté serait appréciée.
- Je souhaite que je pourrais upvote cette question 100 fois. J'ai finalement été en mesure de résoudre mon application se bloque dans la production, et en même temps apprendre un peu plus sur les énumérations et proguard. Très bonne question et merci à tous ceux qui affichent de très bonnes réponses, avec des détails. @Eric Lafortune
Vous devez vous connecter pour publier un commentaire.
Il semble que nous devons demander que les énumérations " les membres sont tenus.
En ajoutant ceci à la proguard fichier de configuration a fonctionné pour moi:
Ou, si vous voulez être plus précis,
GSON jette ce AssertionError quand il ne parvient pas à désérialiser de dénombrement des constantes de données JSON, l'exécution de l'introspection sur les champs de la classe enum. Malheureusement, il avale les détails de la sous-jacentes NoSuchFieldException.
Vous devriez assurez-vous que vous conservez les noms des champs de type enum (et de champs en général) qui sont en série. Par défaut, ProGuard peut renommer ou même de les supprimer. Par exemple, avec certains caractères génériques:
<fields>
ici un espace réservé pour le nom des champs de type enum, ou doit-elle être écrite comme-est?Il est déjà suggéré que vous avez besoin pour configurer Proguard de façon à ce qu'il conserve tous les enum liées à des objets sérialisés intacte. Je n'aime pas vraiment le fait que j'ai explicitement la liste de tous mes énumérations, cette solution est difficile à maintenir. Une légèrement meilleure solution que j'ai développée est la suivante.
Utiliser une interface vide pour indiquer qu'une classe ou enum prend part à Gson de la sérialisation:
Utiliser un Proguard config qui tient à la fois de l'interface et de toutes les classes/les énumérations que sa mise en oeuvre:
C'est elle, aussi longtemps que vos classes et les énumérations, utiliser l'interface, vous devriez être OK. Vous pouvez également appliquer la présence de cette interface dans votre sérialisation/désérialisation des méthodes, afin de ne pas oublier lors de l'ajout d'une nouvelle classe plus tard:
Également dans votre configuration de la ligne avec com.google.gson.des exemples.android.de modèle.** { * ;} "se rapporte à certains de Google connexes exemple de code, donc je ne pense pas que c'est nécessaire.
Après l'exécution dans le même problème, je suis passé par la et a examiné la résultante APK décompilé. Je crois que le problème est lié à certains type enum perdre de ses membres au cours de l'obscurcissement.
Assurez-vous de garder les énumérations:
Aussi - assurez-vous que TOUTES les classes utilisées dans GSON sont retenus:
Voir plein de config @ pastebin.com/r5Jg3yY2
Dans mon cas, proguard a été configuré pour
-keep
classes individuelles touché par Gson, mais l'erreur a disparu lorsque j'ai configuré proguard de conserver la paquet où ces classes résidé: