ProGuard для Android и GSON
Я настраиваю ProGuard для своего проекта Android. Мой проект также использует GSON.
Я исследовал конфигурации ProGuard на предмет совместимости с GSON и Android и наткнулся на этот пример, предложенный Google-gson https://code.google.com/p/google-gson/source/browse/trunk/examples/android-proguard-example/proguard.cfg .
Конфигурация ProGuard скопирована ниже:
##---------------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 ----------
Вопросы:
Я вижу, что этот файл не обновлялся с 2011 года, он по-прежнему рекомендуется к использованию? Я спрашиваю, потому что Android / GSON с тех пор немного изменился, поэтому я не знаю, сколько из вышеперечисленного ненужного или неправильного.
Если это не рекомендуется, существует ли новая рекомендуемая конфигурация ProGuard для GSON в Android?
Переведено автоматически
Ответ 1
Я думаю, что большинство из тех настроек, которые у вас есть, уже включены в Android SDK по умолчанию.
Таким образом, вы можете удалить большинство из них, просто оставив в разделе, посвященном GSON.
Я разрабатываю в Eclipse, используя Android SDK Tools 22.6.3 и любую версию ProGuard, которая поставляется с этим.
Вот что я использую для GSON 2.2.4 (согласно их примеру):
##---------------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.** { *; }
Это выглядит точно так же, как то, что у вас есть, за исключением того, что мне не нужна строка о аннотациях.
Вы можете видеть, что я прокомментировал некоторые классы, которые добавил сам. Если вы сериализуете / десериализуете свои собственные классы, вам нужно объявить их здесь вместо ссылки на mypersonalclass.data.model
. Это действительно важно, так как вы не хотите, чтобы ProGuard запутывал имена полей или классов, которые GSON использует для сериализации.
Я всегда оставляю там подобные комментарии, поэтому знаю, как настроить следующую библиотеку или приложение.
Ответ 2
Предыдущий ответ перестал работать у меня недавно, вероятно, из-за некоторых изменений в Android (теперь вместо Proguard используется R8). Конфигурация, которую я использую сейчас, следующая (исходный код - примеры GSON):
##---------------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 * extends 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>;
}
# Retain generic signatures of TypeToken and its subclasses with R8 version 3.0 and higher.
-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken
-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken
##---------------End: proguard configuration for Gson ----------
Я обнаружил, что классы, поля которых помечены @SerializedName , не обязательно указывать явно, если они не являются внутренними классами.
Ответ 3
В моем случае я просто использовал GSON для десериализации JSON в объект. Поэтому было достаточно добавить следующую строку в файл proguard.
-keep class your.data.object.modals.package.** { <fields>; }
Ответ 4
В моем случае я добавил вышеуказанное, но по-прежнему получал ошибку, пока в моем gradle уровня приложения я не изменил compile 'org.immutables:gson:2.4.6'
на provided 'org.immutables:gson:2.4.6'
. Возможно, кто-то более просвещенный сможет объяснить, почему, но это решило мою проблему.