Android Proguard 混淆详解(APK,librar
今天这个Proguard 混淆单拿出来,是因为确实被恶心到了。本来混淆这块挺简单的,没太注意,但却出现了好多奇奇怪怪的问题,所以我这块系统的整理一下混淆的集中方式和遇到的问题。
一、什么是ProGuard技术?
废话不多说,直接去官网看去ProGuard官网
概括一下就是:
- 压缩(shrinks) :检查并移除代码中无用的类,字段,方法,属性。
- 优化(optimizes):对字节码进行优化,移除无用的指令。
- 混淆(obfuscates):使用a,b,c,d等简短而无意义的名称,对类,字段和方法进行重名,这样即使代码被逆向工程,对方也比较难以读懂。
- 预检测(Preveirfy):在Java平台上对处理后的代码进行再次检测。
总结一下就是:防止反编译拿到核心代码。注:混淆是不可逆的,注意保护好原码。
二、Android 混淆的几种方式
1. ProGuard之配置混淆
-
App混淆(统一配置混淆规则)
app混淆较为简单 在 build.grade (Module:app)的配置文件中打开配置如下
buildTypes {
release {
minifyEnabled true //是否启动混淆 ture:打开 false:关闭
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
接下来编辑proguard-rules.pro文件即可 编辑规则请看
Android studio生成arr包并混淆 中 混淆 ProGuard常用语法
-
module单独配置混淆规则 (推荐)
在 build.grade (Module:library)的配置文件中使用如下配置:
buildTypes {
release {
consumerProguardFiles 'proguard-rules.pro'
}
然后编辑目录下的proguard-rules.pro文件即可
注意
:
- 主模块的混淆开关配置会直接影响到子模块,也就是说如果你的主模块开启的混淆,就算你的子模块关闭混淆开关,最终子模块还是会被混淆的。
- 子模块混淆文件的指定是通过consumerProguardFiles这个属性来指定的,并不是proguardFiles 属性,无需配置其他的选项,只需要配置consumerProguardFiles属性即可。该属性表示在打包的时候会自动寻找该module下我们指定的混淆文件对代码进行混淆。
2. ProGuard之@Keep注解混淆
proguard配置混淆的方式太麻烦了,而且不直观,可能会出错。所以Google有了官方的注解混淆的方法@keep
@keep注解是com.android.support:support-annotationsn内的一个方法,所以我们要在
dependencies 导入如下代码
dependencies {
implementation 'com.android.support:support-annotations:28.0.0'
}
编辑项目目录下的proguard-rules.pro文件 添加如下代码
#打印混淆信息
-verbose
#代码优化选项,不加该行会将没有用到的类删除,这里为了验证时间结果而使用,在实际生产环境中可根据实际需要选择是否使用
-dontshrink
-dontwarn android.support.annotation.Keep
#保留注解,如果不添加改行会导致我们的@Keep注解失效
-keepattributes *Annotation*
-keep @android.support.annotation.Keep class **{
@android.support.annotation.Keep <fields>; #不混淆变量
@android.support.annotation.Keep <methods>; #不混淆方法
}
然后你就可以这样进行设置哪些方法和变量不进行混淆
了
@Keep
public class Sample {
@Keep
public String TAG = "Sample";
@Keep
public String getTAG() {
return TAG;
}
}
三、Android proguardFiles混淆文件配置方式
1. proguard-android.txt
通常我们配置混淆文件都是如下这种方式
android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
proguard-android.txt中没有开启optimizes(优化)和一些默认配置选项。
2. proguard-android-optimize.txt
开启optimize一些默认配置选项如下
android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
对于发布的release版本应使用proguard-android-optimize.txt,此文件主要配置的是一些默认的proguard配置
四、混淆问题整理
1. 关于Android Library上传到bintray混淆源码问题
关于上传bintray云仓库请查看文章Android Library上传到JCenter仓库最佳实践姿势
我在上传混淆后的包的时候 遇到了 引用aidi接口的class文件 在本地build的arr混淆没有问题,但是用代码直接上传到云仓库,引入到项目中却部分类没有混淆,导致引用错误。
查了好久 发现是proguard-rules.pro 中的一个配置文件导致的错误。
#保留注解参数
-keepattributes SourceFile
这个在官方文档中找到了解释
但是我看了还是不明白为什么会导致同步到bintray的时候会报错,线下build却没有问题。
相关文档地址-keepattributes
如果大神知道其中原理,下方留言解惑,感激不尽。
2. 关于proguard 与 @keep共用问题
proguard 与 @keep可以共用,但是在使用@keep注解时,一定要在proguard-rules.pro文件中填写@keep规则,否则会出现// $FF: Couldn't be decompiled
问题。