web-dev-qa-db-fra.com

Comment dire à ProGuard de tout garder dans un package particulier?

Mon application a de nombreuses activités et utilise également une bibliothèque native. Avec la configuration par défaut de ProGuard qu'Eclipse génère, ProGuard supprime beaucoup de choses - méthodes OnClick, membres statiques, méthodes de rappel que ma bibliothèque native utilise ... Existe-t-il un moyen simple de demander à ProGuard de ne rien supprimer de mon package? La suppression d'éléments n'économise qu'environ 2,5% de la taille de l'application, mais casse complètement mon application. Le configurer, le tester et le maintenir classe par classe dans la configuration ProGuard serait un problème.

49
ggurov

Comme résultat final, j'ai trouvé que le simple fait de garder tous les membres de la classe n'est pas suffisant pour le bon travail de ma candidature, ni nécessaire. J'ai ajouté au fichier de paramètres ceci:

-keepclasseswithmembers class * {
    void onClick*(...);
}
-keepclasseswithmembers class * {
    *** *Callback(...);
}

Le cas avec onClick * concerne toutes les méthodes que j'adresse dans Android: onClick attribue dans les fichiers de mise en page .xml (je commence les noms de toutes ces méthodes par 'onClick').

Le cas avec * Callback concerne toutes les méthodes de callback que j'appelle à partir de mon code natif (via JNI). Je place un suffixe "Callback" au nom de chacune de ces méthodes.

J'ai également ajouté quelques lignes pour certains cas spéciaux avec des variables que j'utilise à partir du code natif, comme:

-keep class com.myapp.mypackage.SomeMyClass {
    *** position;
}

(pour une variable avec le nom 'position' dans une classe avec le nom 'SomeMyClass' du package com.myapp.mypackage)

Tout cela est dû au fait que ces onClick, rappels, etc. doivent non seulement être présents, mais également conservés avec leurs noms d'origine. Les autres choses que ProGuard peut optimiser librement.

Le cas avec les méthodes natives est également important, mais pour cela il y avait une déclaration dans le fichier généré à partir d'Eclipse:

-keepclasseswithmembernames class * {
    native <methods>;
}
22
ggurov

Je pense que vous devez au moins ajouter ces drapeaux (modifiez pour vous les noms de packages individuels):

-keep class javax.** { *; }
-keep class org.** { *; }
-keep class Twitter4j.** { *; }

Ajoutez également ces drapeaux:

-dontshrink
-dontoptimize
-dontpreverify

Voici tout mon fichier de configuration: de mon Proguard.cfg:

-dontshrink
-dontoptimize
-dontpreverify
-verbose

-dontwarn javax.management.**
-dontwarn Java.lang.management.**
-dontwarn org.Apache.log4j.**
-dontwarn org.Apache.commons.logging.**
-dontwarn org.slf4j.**
-dontwarn org.json.**


-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 class javax.** { *; }
-keep class org.** { *; }
-keep class Twitter4j.** { *; }

-keepclasseswithmembernames class * {
    native <methods>;
}

-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 *;
}
52
Caspar Harmer