本文部分内容引用自《Android高级进阶》
一,Proguard特性
1.压缩:proguar会分析字节码,检测并移除没有使用到的类,字段,方法和属性。
2.优化:优化Java字节码,移除没有使用到的指令
3.混淆:使用无意义的简短字母组合对类名,字段名,方法名进行重命名。
4.预校检:对上述处理后的代码进行预校检
二,proguar的配置和使用
在要使用混淆的module的build.gradle文件添加如下代码:
android{
......
buildTypes{
release{
minifyEnabled true //true表示使用proguar
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
可以看到,混淆代码涉及到两个文件,其中proguard-android.txt是Proguar默认的混淆配置文件,位于android sdk的tools /proguar 目录中,该文件是对proguar的基本配置,处理默认配置,我们也有根据自己的需要增加配置,这些配置可写到proguard-rules.pro中,proguard-android.txt内容分析:
#混淆时不使用大小写混合类名
-dontusemixedcaseclassnames
#指定不去忽略非公共的类库
-dontskipnonpubliclibraryclasses
#混淆过程打印日子级别
-verbose
#dex打包时会做优化工作,不希望代码经过prohuar的优化和与校检,因此需要去掉两个功能
#不使用优化方案
-dontoptimize
#混淆时不做预校检
-dontpreverify
#如果项目使用到注解,保留注解属性
-keepattributes *Annotation*
#保存native方法不混淆
-keepclasseswithmembernames class * {
native <.methods>;
}
#保持view的getter和setter方法不被混淆,保证动画能执行
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
#保存activity中参数为View的类型的函数,保证xml文件配置的onClick属性能使用
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
#保持枚举类型的函数
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
#保持Parcelable类的CREATOR不被混淆
-keepclassmembers class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator CREATOR;
}
三,编写混淆文件
如果默认的proguard-android.txt 文件的配置不满足具体需求,那么需要配置module根目录的proguard-rules.pro文件。
语法分析:
#代码迭代优化次数,取值1-7,默认5
-optimizationpasses 5
#混淆时记录日志,同时会产生映射文件,生成的映射文件在build/outputs/mapping/release/mapping.txt
-verbose
#指定生成映射文件的名称和路径
-printmapping build/outputs/mapping/release/mymapping.txt
#混淆时采用的算法,参数是谷歌推荐的过滤器算法
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
#不混淆泛型
-keeppattributes Signature
#保留代码行号,这在混淆后代码运行中抛出异常信息时,有利于定位出问题的代码
-keeppattributes SourceFile,LineNumberTable
#保持R类
-keep class **.R$* {
*;
}
#保持自定义控件类不被混淆
-keep classeswithmembers class* {
public<init> (android.content.Context, android.util.AttributeSet);
}
-keep classeswithmembers class* {
public(android.content.Context, android.util.AttributeSet ,int);
}
#保护实现接口Serializable的类中,指定规则的类成员不被混淆
-keepclassmembers class* implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
privatevoidwriteObject(java.io.ObjectOutputStream);
private voidr eadObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
四,prohuar生成的文件
proguar会生成四个文件,分别如下
1.dump.txt :列出生成的apk文件中所有class文件的内部结构。
2.mapping.txt :列出混淆前的Java源码和混淆后的类,方法, 属性名字之间的映射
3.seed.txt :列出未混淆的类和成员
4.usage.txt :列出从apk文件中去除的代码