Android Studio 使用ProGuard 进行混淆,ProGuard是一个压缩,优化和混淆Java 字节码文件的工具, 可以删除无用的类,字段,方法和属性,还可以删除无用的注释,最大限度的优化字节码文件。它还可以使用简短并无意义的名称来重命名已经存在的类,字段,方法和属性。
混淆流程针对于Android 项目, 将其主项目及依赖库中未被使用的类,类成员,方法,属性移除,有助于规避64k 方法数的瓶颈; 同时将类,类成员,方法重命名为无意义的简短名称,增加了逆向工程的难度。混淆会删除项目中无用的资源,有效减小apk 安装包的大小。
混淆有 Shrinking(压缩),Optimization(优化),Obfuscation(混淆), Preverification(预校验) 四项操作。
Build.gradle 的基本配置:
buildTypes { debug { signingConfig signingConfigs.config } release { signingConfig signingConfigs.config minifyEnabled true zipAlignEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } }
minifyEnabled 值为 true, 打开混淆
shrinkResources 值为true, 打开资源压缩
proguardFiles 用于设置proguard 的规则路径
以下情况不能使用混淆:
1)四大组件和Application要在AndroidMainfest.xml 中声明,所以这些都不能混淆
2)R 文件不能混淆,因为有时要通过反射获取资源
3)support 的v4和v7 包中的类不能混淆 - 系统的东西,不要随便动
4)实现了Serializable的类不能混淆,否则反序列化时会出错
5)泛型不能混淆
6)自定义View不能混淆,否则在Layout中使用自定义View时会找不到
7)JNI 调用调用java方法,java 调用的native 方法不要混淆
8)WebView中 JavaScript 的调用方法不能混淆
混淆后会生成mapping.txt 文件,seeds.txt文件, usage.txt 文件
mapping.txt : 记录混淆后路径和原路径的映射关系。 当线上出现问题,获得用户的日志信息后,定位出现问题的文件。
seeds.txt: 未混淆的类和成员,验证是否持有不想混淆的类
usage.txt: 列出apk 被删除的代码
混淆规则:
###-----------基本配置-不能被混淆的------------ -keep public class * extends android.app.Activity -keep public class * extends android.app.Fragment -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 #support.v4/v7包不混淆 -keep class android.support.** { *; } -keep class android.support.v4.** { *; } -keep public class * extends android.support.v4.** -keep interface android.support.v4.app.** { *; } -keep class android.support.v7.** { *; } -keep public class * extends android.support.v7.** -keep interface android.support.v7.app.** { *; } -dontwarn android.support.** # 忽略警告 #保持注解继承类不混淆 -keep class * extends java.lang.annotation.Annotation {*;} #保持Serializable实现类不被混淆 -keepnames class * implements java.io.Serializable #保持Serializable不被混淆并且enum 类也不被混淆 -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(); } #保持枚举enum类不被混淆 -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } #自定义组件不被混淆 -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*(...); } #不混淆资源类 -keepclassmembers class **.R$* { public static <fields>; }