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
В моем случае я добавил выше, но все еще получил ошибку, пока на моем уровне приложения gradle я не изменил compile 'org.immutables:gson:2.4.6'
на provided 'org.immutables:gson:2.4.6'
. Может быть, кто-то более просвещенный может объяснить, почему, но это решило мою проблему.
Ответ 3
Использование -keep является плохой практикой, и вы никогда не должны этого делать. Вы почти никогда не хотите использовать -keep; если вам нужно правило ProGuard, вам обычно нужен один из более конкретных вариантов
-keepclassmembers
- Это защищает только членов класса от сокращения и запутывания.
-keepnames
- позволяет -keepnames
классы и членов, но не запутывать. То есть любой неиспользуемый код будет удален. Но сохраненный код сохранит свои оригинальные имена.
-keepclassmembernames
- неиспользуемые классы удаляются, остальные классы переименовываются, неиспользуемые члены этих классов удаляются, но затем оставшиеся члены сохраняют свои первоначальные имена.
Для получения дополнительной информации, пожалуйста, прочитайте это
PS - это то, что я сделал для Gson
-keepclassmembernames class rscom.pojo.** { <fields>; }