在网上搜索了好多文章都没学懂proguard,还是看看原始文档比较好!
A complete Android application
(来自文档:ANDROID_HOME/tools/proguard/docs/manual/examples.html#application)
-injars bin/classes
-injars libs
-outjars bin/classes-processed.jar
-libraryjars /usr/local/java/android-sdk/platforms/android-9/android.jar
-dontpreverify
-repackageclasses ''
-allowaccessmodification
-optimizations !code/simplification/arithmetic
-keepattributes *Annotation*
#如果星号(*)单独使用,则可以代替任意类。
-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.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
public void set*(...);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * implements android.os.Parcelable {
static android.os.Parcelable$Creator CREATOR;
}
#如果星号配合其它字符使用,则不能代替点(‘.’)。
-keepclassmembers class **.R$* {
public static <fields>;
}
看了上面的代码,基本上都会了吧!
通配符比较麻烦,详情可以看下这个 proguard通配符(文章中和上面注释处有点出入,但上面代码是Android官方的,且测试通过)
特别说明:Android默认规则中未保留Native方法,需要自己写规则。
#保留Native方法
-keepclasseswithmembers class * {
native <methods>;
}
之前看了好多文章,对与‘-keep’规则一直没弄明白。因为Android自己也有个Keep(androidx.annotation.Keep),老是搞混。
androidx.annotation.Keep:Denotes that the annotated element should not be removed when
the code is minified at build time. This is typically used
on methods and classes that are accessed only via reflection
so a compiler may think that the code is unused.
从上面注释可以看出,注解哪个元素,就保留哪个元素名称且不被移除。注解类则保留类名且不被移除,注解方法和变量同理。
-keep [,modifier,...] class_specification
Specifies classes and class members (fields and methods) to be preserved as entry points to your code. For example, in order to keep an application, you can specify the main class along with its main method. In order to process a library, you should specify all publicly accessible elements.
而-keep,是可以实现不能功能的。
#保留类名
-keep class com.demo.data
#保留类和所有方法
-keep class com.demo.data{<methods>;}
#保留类和所有变量
-keep class com.demo.data{<fields>;}
#保留类和所有方法及变量
-keep class com.demo.data{*;}
-keepclassmembers [,modifier,...] class_specification
Specifies class members to be preserved, if their classes are preserved as well. For example, you may want to keep all serialization fields and methods of classes that implement the Serializable interface.
注释说了,这个只保留成员(成员变量和成员方法),不保留类。
#keep all serialization fields and methods
-keepclassmembers class * implements java.io.Serializable {
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();
}
上面这个规则是用于标准serialization的,不适用于Android。比如我是用Gson来解析数据的,我把所有数据类都实现的serialization接口。保留规则是这样写的。
-keepclassmembers class * implements java.io.Serializable{<fields>;}
更多详细信息,请直接查看官方文档吧(地址在文章首部)