ProGuard
1.1、ProGuard简介

ProGuard是一个开源的Java字节码的压缩、优化、混淆、预校验工具。

由于Java字节码很容易被反编译,而且很多时候,我们需要对字节码进行优化,ProGuard就是一个不错的选择。

ProGuard官网:https://www.guardsquare.com/en/proguard

1.2、ProGuard分支

ProGuard是开源的,很多人或者组织可能会对它进行优化,Facebook就对他进行了优化, 不过,它没有增加任何的功能,只是让它运行的更快。地址:https://github.com/facebook/proguard

1.3、ProGuard与Android

Android SDK自带了ProGuard,位于${ANDROID_HOME}/tools/proguard, 下面是其目录结构:

/usr/local/share/android-sdk/tools/proguard
├── README
├── ant
│   └── task.properties
├── bin
│   ├── proguard.sh
│   ├── proguardgui.sh
│   └── retrace.sh
├── lib
│   ├── proguard.jar
│   ├── proguardgui.jar
│   └── retrace.jar
├── docs
│   └── ...
├── examples
│   └── ...
├── license.html
├── proguard-android-optimize.txt
├── proguard-android.txt
└── proguard-project.txt

Android SDK自带的ProGuard针对Android开发预备了混淆脚本配置文件,proguard-android.txtproguard-android-optimize.txt,它们的区别就是proguard-android-optimize.txt打开了优化开关,在混淆之前先进行优化,而proguard-android.txt比较保守, 不进行优化。我们一般要进行优化的。

我们要在使用AndroidStudio进行开发的工程中开启ProGuard, 就需要在build.gradle配置文件中进行相关的配置。配置方法如下:

apply plugin: 'com.android.application' //'com.android.library'
android {
    ...
    buildTypes {
        debug {
            minifyEnabled false
            signingConfig signingConfigs.release
        }

        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
            signingConfig signingConfigs.release
        }
    }
}

这里,我们一般在构建Debug包的时候,不开启ProGuard,只在构建Release包的时候才会开启。minifyEnabled false就是指示是否要开启ProGuard

如果开启了ProGuard,就要说明配置脚本的路径。proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'表示使用${ANDROID_HOME}/tools/proguard/proguard-android.txt作为默认的配置文件, 因为默认的配置文件已经为我们配置了常规的一些指令,简化开发者。通常,我们会把proguard-android.txt修改为proguard-android-optimize.txt, 也就是,我们会做优化。第二个参数proguard-project.txt就是我们自己要编写的配置文件路径,一般都是在模块的根目录下。

1.4、ProGuard原理

ProGuard依次由压缩(Shrink)、优化(Optimize)、混淆(Obfuscate)和预校验(PreVerify)四个步骤组成, 每个步骤都是可选的,我们可以通过指令来决定执行其中的哪几个步骤。

每个步骤执行的工作是:

  • 压缩(Shrink)
    检测并移除代码中无用的类、类中无用的字段、类中无用的方法、方法中无用的代码段(Dead Code)。
  • 优化(Optimize)
    对字节码中的虚拟机指令进行优化,使得运行速度更快。
  • 混淆(Obfuscate)
    使用a,b,c,d这样简短的、对人类来说不可读的名称,对类命、类的字段和方法、变量等进行重命名。 这不仅仅让反编译后更难读懂,也能减小生成的Jar包或者Dex文件的大小。
  • 预检(PreVerify)
    经过前面3步骤的处理后,很可能使得代码不可用了,所以进行预检,确保加载的class文件是可执行的。
1.5、ProGuard配置文件

ProGuard配置文件是由一系列的指令组成的,每个指令以-开头。

AndroidStudio中,书写ProGuard配置文件的指令是会有提示的, 这个非常赞,避免我们写错指令和经常查询文档。 因为ProGuard配置文件的很多指令是由多个单词组成的,指令名非常的长,写错的可能性也是很大的。