34 votes

ProGuard et Gson sur Android (ClassCastException)

Je vais avoir un sacré bout de temps avec Gson et ProGuard. J'ai un objet simple et quand je lis la méthode tojson, enregistrer sqllite et lire à partir de la base de données afin de charger le json retourné à mon objet, je reçois un java.lang.classcastexception. Si je n'utilise pas ProGuard, tout fonctionne très bien.

J'ai vérifié que la chaîne json envoyée et obtenu à partir de la base de données est la même. L'exception n'est levée lorsqu'il se convertit en json, mais plutôt quand j'essaie d'accéder à l'objet.

Voici mon objet simple:

public class ScanLog extends ArrayList<SingleFrame>
{
     private static final long serialVersionUID = 1L;

     public ScanLog()
     {

     }
}

public final class SingleFrame 
{
    public int Position;
    public int Time;
    public Map<Integer,String> MainDataMap;
    public Map<Integer,String> DataMap;

    public SingleFrame(int position, int time, 
                    Map<Integer,String> mainDataMap, Map<Integer,String> dataMap)
    {
        this.Position = position;
        this.Time = time;
        this.MainDataMap = mainDataMap;
        this.DataMap = dataMap;
    }

}

Tous les autres aspects de mon application sont très bien, mais quelque chose avec proguard est la cause de cette fermeture....J'ai essayé toutes sortes de garder les commandes dans le proguard.cfg mais je ne suis pas sûr de ce que je fais est juste.

EDIT - AJOUT DE PROGUARD.CFG

-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-dontshrink
-dontoptimize

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService

#keep all classes that might be used in XML layouts
-keep public class * extends android.view.View
-keep public class * extends android.app.Fragment
-keep public class * extends android.support.v4.Fragment

#keep all classes
-keep public class *{
public protected *;
}

#keep all public and protected methods that could be used by java reflection
-keepclassmembernames class * {
    public protected <methods>;
}


-keepclasseswithmembernames class * {
    native <methods>;
}

-keep public class org.scanner.scanlog.SingleFrame


-keepclassmembers class org.scanner.scanlog.ScanLog { 
        private <fields>; 
        public <fields>; 
}

-keepclassmembers class org.scanner.scanlog.SingleFrame { 
        private <fields>; 
        public <fields>; 
}

-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

-dontwarn **CompatHoneycomb
-dontwarn org.htmlcleaner.*
#-keep class android.support.v4.** { *; }

EDIT - Bon, je suis ACRA mis en place avec succès dans mon application, assez impressionnant dispositif! Voici la trace de la pile:

java.lang.ClassCastException: java.lang.Object
    at org.scanner.activity.ReaderMainActivity.AdvanceScanLog(SourceFile:1499)
    at org.scanner.activity.r.onProgressChanged(SourceFile:271)
    at android.widget.SeekBar.onProgressRefresh(SeekBar.java:89)
    at android.widget.ProgressBar.doRefreshProgress(ProgressBar.java:507)
    at android.widget.ProgressBar.refreshProgress(ProgressBar.java:516)
    at android.widget.ProgressBar.setProgress(ProgressBar.java:565)
    at android.widget.AbsSeekBar.trackTouchEvent(AbsSeekBar.java:337)
    at android.widget.AbsSeekBar.onTouchEvent(AbsSeekBar.java:292)
    at android.view.View.dispatchTouchEvent(View.java:3932)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:906)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:906)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:906)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:906)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:906)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:906)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:906)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:906)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:906)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1784)
    at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1157)
    at android.app.Activity.dispatchTouchEvent(Activity.java:2181)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1759)
    at android.view.ViewRoot.deliverPointerEvent(ViewRoot.java:2336)
    at android.view.ViewRoot.handleMessage(ViewRoot.java:1976)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:143)
    at android.app.ActivityThread.main(ActivityThread.java:4263)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
    at dalvik.system.NativeStart.main(Native Method)

70voto

Guy Points 5270

Pour la dernière version du fichier de configuration de proguard recommandé, veuillez consulter l'exemple de proguard android fourni par gson à: http://code.google.com/p/google-gson/source/browse/trunk/examples/android-proguard-example /proguard.cfg

26voto

Jerry Points 115

Ces paramètres dans la configuration ont fonctionné pour moi dans l'une de mes applications:

 # Add the gson class
-keep public class com.google.gson

# Add any classes the interact with gson
-keep class com.someapp.android.models.ChatModel { *; }
-keep class com.someapp.android.models.FeedModel { *; }

# Add the path to the jar
-libraryjars /Users/someuser/Documents/workspace/someapp/lib/gson-1.7.1.jar
 

J'espère que ceci vous aidera.

14voto

Daddyboy Points 806

L'application des modifications trouvées dans l' exemple Android dans le projet Gson a fonctionné pour moi

Les lignes nécessaires étaient:

 -keepattributes Signature
-keep class sun.misc.Unsafe { *; }
# and keeping the classes that will be serialized/deserialized
 

6voto

HTLD Points 51

Je sais que la question initiale a été résolu par l'adoption d'une approche différente, mais j'ai eu très semblable à la question en utilisant flexjson et Proguard sur Android, et je l'ai résolu, au cas où quelqu'un s'exécute en eux-mêmes.

Lors de la conversion de retour de JSON à mon objet de valeur, qui a inclus des ArrayLists, je voudrais obtenir le même ClassCastException. Je l'ai eu à travailler par essentiellement avoir de la dissimulation de l'activé mais en tournant toutes les parties de la dissimulation de l'arrêt (-de tout garder, -keepclassmembers tout et -keepattributes tout) et ensuite travailler vers l'arrière en permettant à des choses un peu à la fois.

Le résultat, de maintien de l'ensemble de la flexjson de la bibliothèque:

-keep class flexjson**
--keepclassmembers class flexjson** {
   *;
}

et en gardant la Signature et à l' Annotation de l'attribut:

-keepattributes Signature, *Annotation*

J'ai été en mesure d'utiliser le flexjson bibliothèque sans incident après que, dans un proguarded, version de mon application.

1voto

THelper Points 5527

Il ne ressemble à votre sont de maintenir le tout à partir de votre classe (champs, les méthodes et la classe elle-même). Mais assurez-vous que vous pouvez ajouter -printseeds outputfile.txt de la proguard.fichier cfg pour vérifier que proguard vraiment garder tout ce dont vous avez besoin une fois que l'obfuscation est fait.

BTW, vous pourriez penser à l'ajout de quelque chose comme l'ACRA ou Android à Distance stacktrace qui permet d'inspecter stacktraces sur une application.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X