ProGuard With Gradle
在官方Android开发者文档中有一篇很nice的文章why you should use Proguard when you building your application.但是文档还没有涉及到新的Gradle
构建系统。
Android的Gradle
构建系统有一个内置的任务来运行ProGuard
。Android Tools site有关ProGuard的内容只有一小部分,重要的细节都没有讲出来。
对于一个特别的 BuildType 要打开ProGuard
任务,只要设置minifyEnabled
的值为true就可以了。默认情况下,debug build type的ProGuard
是关闭的(minifyEnabled false
),这点大家都很清楚。
接下来使用两个默认Android文件中的一个作为ProGuard
的基本配置文件。如果你的Android项目已经很久了,你的基本配置文件估计也该更新了.新的文件运行的会更好,下面两个文件,保守的选择是non-optimized那个文件,optimized文件会带来意想不到的麻烦。
1 2 3 | proguardFile getDefualtProguardFile('proguard-android.txt') //or proguardFile getDefualtProguardFile('proguard-android-optimized.txt') |
为项目添加所需要的ProGuard
规则,我个人比较喜欢把每个library的ProGuard
规则单独的放一个文件,这样我就可以在不同的项目中复用了。这些文件的最简单放置位置是在Project的最顶层,也就是和build.gradle文件同一级(添加到项目默认的地方就好了)。我在GitHub上开始收集常用的Libraries的ProGuard Files.当从一个项目中不在使用某种依赖库时,使用这种方法就可以很容易的移除相关ProGuard的配置,非常方便。
1 2 | proguardFile 'proguard-google-play-services.txt' proguardFile 'proguard-gson.txt' |
另外我们还需要为项目中一些比较明确的地方添加一个模糊的ProGuard
配置文件,比如:所有需要使用Gson解析的类就需要使用这样的规则。
1 2 | -keep class com.jabin.sample.BuildConfig {*;} -keep class com.jabin.sample.model.User {*;} |
把所有的文件放在一块,基本的ProGuard
配置就和下面相似了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | android { ... buildTypes { debug{ debuggable true minifyEnabled false } release { debuggable false minifyEnabled true proguardFile 'proguard-bugsense.txt' proguardFile 'proguard-eventbus.txt' proguardFile 'proguard-google-play-services.txt' proguardFile 'proguard-gson.txt' proguardFile 'proguard-project.txt' proguardFile getDefaultProguardFile('proguard-android.txt') } } } |
还有一个点需要注意,一定要保存每次在release下build产生的mapping.txt文件,这个文件保存了混淆前后的信息,它在/build/{appname}/proguard/{buildvariant}
目录下。你可以把它上传到异常捕获平台(Umeng,BugSense,Crashlytics,etc)去分析崩溃日志,会有很大帮助。
另外,作为一个Android应用开发者,你会使用ProGuard
去混淆、优化、缩减你的应用,但是在build release version时,它往往会花费一段令我们头疼的时间,如果你的Project过大的话。这时我想你有必要了解一下Squad Leader库,它让这个步骤更简单。Squad leader包含两个注解(Annotation):@Keep
& @Keepname
,你可以讲这个两个注解添加到class、 method 或者 field,但@KeepName
注解的对象是一定要被使用的,如果你不确定这个对象会不会被使用,那可以用@Keep来注解。
dependencies {
compile 'nl.littlerobots.squadleader:squadleader:<latest-version>'
}
引入包后,就可以通过注解合适的class,field or method 来注解那些你不想使用ProGuard
来处理的对象。Example:
import nl.littlerobots.squadleader.Keep;
import nl.littlerobots.squadleader.KeepName;
public class Example {
@KeepName
// this field will be stripped if it's unused in your code
public String stringTheory;
@Keep
// this field will be kept, even if it's unused
public boolean myBool;
}
或者
@Keep
// this class is not stripped or obfuscated
public class Example {
public String stringTheory;
public boolean myBool;
}
这个与ProGuard
之间没有影响,在build relaese version时,ProGuard
还是会作用于其他libraries。更详细的信息请看Squad leader