ProGuard für Android und GSON

Lesezeit: 7 Minuten

Ich richte ProGuard für mein Android-Projekt ein. Mein Projekt verwendet auch GSON.

Ich habe ProGuard-Konfigurationen auf Kompatibilität mit GSON und Android untersucht und bin auf dieses von google-gson angebotene Beispiel gestoßen https://code.google.com/p/google-gson/source/browse/trunk/examples/android-proguard-example/proguard.cfg.

ProGuard-Konfiguration unten kopiert:

##---------------Begin: proguard configuration common for all Android apps ----------
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
-verbose
-dump class_files.txt
-printseeds seeds.txt
-printusage unused.txt
-printmapping mapping.txt
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-allowaccessmodification
-keepattributes *Annotation*
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
-repackageclasses ''

-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
-dontnote com.android.vending.licensing.ILicensingService

# Explicitly preserve all serialization members. The Serializable interface
# is only a marker interface, so it wouldn't save them.
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}

# Preserve all native method names and the names of their classes.
-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);
}

# Preserve static fields of inner classes of R classes that might be accessed
# through introspection.
-keepclassmembers class **.R$* {
  public static <fields>;
}

# Preserve the special static methods that are required in all enumeration classes.
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keep public class * {
    public protected *;
}

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}
##---------------End: proguard configuration common for all Android apps ----------

##---------------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.** { *; }

##---------------End: proguard configuration for Gson  ----------

Fragen:

  1. Ich sehe, dass diese Datei seit 2011 nicht mehr aktualisiert wurde. Wird sie weiterhin zur Verwendung empfohlen? Ich frage, weil sich Android/GSON seitdem ziemlich verändert hat, also weiß ich nicht, wie viel davon unnötig oder falsch ist.

  2. Wenn dies nicht empfohlen wird, gibt es eine neue empfohlene ProGuard-Konfiguration für GSON in Android?

ProGuard fur Android und GSON
Richard Le Mesurier

Ich denke, die meisten dieser Einstellungen, die Sie dort haben, sind bereits standardmäßig im Android SDK enthalten.

Sie können also die meisten von ihnen entfernen, indem Sie einfach den Abschnitt belassen, der GSON gewidmet ist.


Ich entwickle in Eclipse mit Android SDK Tools 22.6.3 und der damit gelieferten Version von ProGuard.

Folgendes verwende ich für GSON 2.2.4 (nach ihrem Vorbild):

##---------------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

# 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 mypersonalclass.data.model.** { *; }

Es sieht genauso aus wie das, was Sie haben, außer dass ich die Zeile mit den Anmerkungen nicht benötige.


Sie können sehen, dass ich einige Klassen auskommentiert habe, die ich selbst hinzugefügt habe. Wenn Sie Ihre eigenen Klassen serialisieren/deserialisieren, müssen Sie sie hier anstelle des Verweises auf deklarieren mypersonalclass.data.model. Dies ist wirklich wichtig, da Sie nicht möchten, dass ProGuard die Feld- oder Klassennamen verschleiert, die GSON für die Serialisierung verwendet.

Ich hinterlasse diese Art von Kommentaren immer dort, damit ich weiß, wie ich die nächste Bibliothek oder App konfigurieren muss.

  • Das kommt übrigens von hier: google-gson.googlecode.com/svn/trunk/examples/…

    – kräh

    7. März 2015 um 20:27 Uhr

  • Nachdem ich viel QA gesucht hatte, kam ich hierher. Es macht mich glücklich. Danke Richard. eine Anmerkung, “mypersonalclass.data.model”, dies ist für mich nicht erforderlich. einfach checken.

    – Noundla Sandeep

    8. Januar 2016 um 8:06 Uhr

  • @Noundla hat die Antwort aktualisiert, um das zu erklären mypersonalclass.data.model ist ein Platzhaltertext und sollte auf Ihr eigenes Datenmodellpaket zeigen.

    – Richard Le Mesurier

    8. Januar 2016 um 8:52 Uhr

  • Links sind jetzt kaputt

    – Tejzeratul

    26. Mai 2016 um 19:31 Uhr

  • Tausend Dank, hatte ein Modell in einem anderen Paket und musste diesen Pfad hinzufügen!

    – RESTfulGeoffrey

    16. Mai 2020 um 2:06 Uhr

Die vorherige Antwort funktionierte für mich kürzlich nicht mehr, wahrscheinlich aufgrund einiger Änderungen in Android (R8 wird jetzt anstelle von Proguard verwendet). Die Konfiguration, die ich jetzt verwende, ist wie folgt (Quelle – GSON-Beispiele):

##---------------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
-dontwarn sun.misc.**
#-keep class com.google.gson.stream.** { *; }

# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { <fields>; }

# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * implements com.google.gson.TypeAdapter
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer

# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
  @com.google.gson.annotations.SerializedName <fields>;
}

##---------------End: proguard configuration for Gson  ----------

Ich habe herausgefunden, dass Klassen, deren Felder mit @SerializedName annotiert sind, nicht explizit aufgelistet werden müssen, es sei denn, es handelt sich um innere Klassen.

In meinem Fall habe ich nur GSON zum Deserialisieren von JSON in ein Objekt verwendet. Es reichte also aus, die folgende Zeile zur proguard-Datei hinzuzufügen.

-keep class your.data.object.modals.package.** { <fields>; }

  • es wird nur ein * benötigt.

    – lasec0203

    25. September 2020 um 2:46 Uhr

In meinem Fall habe ich das Obige hinzugefügt, aber immer noch einen Fehler erhalten, bis ich mich in meinem App-Level-Gradle geändert habe compile 'org.immutables:gson:2.4.6' zu provided 'org.immutables:gson:2.4.6'. Vielleicht kann jemand, der aufgeklärter ist, erklären, warum, aber das hat mein Problem gelöst.

Die Verwendung von -keep ist eine schlechte Praxis und Sie sollten dies niemals tun. Sie möchten fast nie -keep verwenden; Wenn Sie eine ProGuard-Regel benötigen, möchten Sie normalerweise eine der spezifischeren Varianten

-keepclassmembers – Dies schützt nur die Mitglieder der Klasse vor Schrumpfung und Verschleierung.

-keepnames – Dies ermöglicht das Schrumpfen für Klassen und Mitglieder, aber keine Verschleierung. Das heißt, jeder nicht verwendete Code wird entfernt. Der beibehaltene Code behält jedoch seine ursprünglichen Namen.

-keepclassmembernames – Nicht verwendete Klassen werden entfernt, die verbleibenden Klassen werden umbenannt, nicht verwendete Mitglieder dieser Klassen werden entfernt, aber die verbleibenden Mitglieder behalten ihre ursprünglichen Namen.

Für weitere Informationen lesen Sie bitte dies

PS – das habe ich für Gson gemacht

-keepclassmembernames class rscom.pojo.** { <fields>; }

  • Was sind die Gründe dafür, dass “die Verwendung von -keep eine schlechte Praxis ist und Sie es niemals tun sollten”? Übrigens, keepclassmembernames funktioniert in unserem Setup nicht, alle Felder werden entfernt. Nur keep oder keepclassmembers hält sie wirklich.

    – gmk57

    30. Juli 2020 um 14:55 Uhr


  • Was sind die Gründe dafür, dass “die Verwendung von -keep eine schlechte Praxis ist und Sie es niemals tun sollten”? Übrigens, keepclassmembernames funktioniert in unserem Setup nicht, alle Felder werden entfernt. Nur keep oder keepclassmembers hält sie wirklich.

    – gmk57

    30. Juli 2020 um 14:55 Uhr


997250cookie-checkProGuard für Android und GSON

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy