混淆优点:
- 防止第三方反编译,窃取自己的劳动成果;
- 减小 apk 体积,节省资源;
混淆带来的问题:
做过 Android 开发的童鞋应该都有此体会,明明我的 debug 包在调试的时候一切正常啊,发布到线上了怎么就 crash 了呢?一般涉及到 debug 和 release 包的时候问题,很多都是由于混淆引起的,因此在这里对混淆做一个小小的总结,以便于后续备用。
1. 混淆原则:
- 反射用到的类不混淆;
- JNI 方法不混淆;
- AndroidMainfest 中的类不混淆,四大组件和 Application 的子类和 Framework 层下所有的类默认不会进行混淆;
- Parcelable 的子类和 Creator 静态成员变量不混淆,否则会产生android.os.BadParcelableException 异常;
- 使用 GSON、fastjson 等框架时,所写的 JSON 对象类不混淆,否则无法将 JSON 解析成对应的对象;
- 使用第三方开源库或者引用其他第三方的 SDK 包时,需要在混淆文件中加入对应的混淆规则;
2. 混淆语法:
通用匹配规则:
1234567891011? 匹配单个字符* 匹配类名中的任何部分,但不包含额外的包名** 匹配类名中的任何部分,并且可以包含额外的包名% 匹配任何基础类型的类型名... 匹配任意数量、任意类型的参数<init> 匹配任何构造器<ifield> 匹配任何字段名<methods> 匹配所有方法方法* 匹配任意类型名 ,包含基础类型/非基础类型*(当用在类内部时) 匹配任何字段和方法$ 指内部类不混淆某个包下所有的类:
1-keep class packageName.**{*;}不混淆指定的类:
1-keep class packageName.className{*;}不混淆某个类的构造函数:
123-keep clsss packageName.className {public <init>(...);}不混淆某个接口:
1-keep interface packageName.interfaceName{*;}不混淆接口的实现:
1-keep class * implements packageName.interfaceName{*;}
3. Android app/library 混淆配置:
app 配置:
123456789android {buildTypes {release {minifyEnabled trueshrinkResources trueproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}}aar/jar: 开源库中可以依赖此标志来指定库的混淆方式,此会将*.pro文件打包进入aar中,库混淆时候会自动使用此混淆配置文件,以 consumerProguardFiles 方式加入的混淆具有以下特性:
- *.pro 文件会包含在 aar 文件中;
- pro 文件中的配置会在混淆的时候被使用;
- consumerProguardFiles 配置只针对此 aar 进行混淆配置;
- consumerProguardFiles 配置只对库文件有效,对应用程序无效;
|
|
4. proguard 混淆后输出:
- dump.txt 描述 apk 文件中所有类文件间的内部结构;
- mapping.txt 列出了原始的类,方法,和字段名与混淆后代码之间的映射;
- seeds.txt 列出了未被混淆的类和成员;
- usage.txt 列出了从 apk 中删除的代码
5. 自定义输出 mapping.txt:
|
|
6. 下面列举一些常用的混淆配置:
|
|