使用Proguard混淆Gradle项目
1.我们为什么要用Proguard进行混淆?
ProGuard是最受欢迎的Java字节码优化器。 它使您的Java和Android应用程序缩小了90%,速度提高了20%。 ProGuard还通过模糊类,字段和方法的名称来提供对逆向工程的最小保护。
按照官网说法,proguard包括四个功能:
shrinker(压缩): 检测并移除没有用到的类,变量,方法和属性;
optimizer(优化): 优化代码,非入口节点类会加上private/static/final, 没有用到的参数会被删除,一些方法可能会变成内联代码。
obfuscator(混淆): 使用短又没有语义的名字重命名非入口类的类名,变量名,方法名。入口类的名字保持不变。
preverifier(预校验): 预校验代码是否符合Java1.6或者更高的规范
下面是官网的一张图:
2.配置文件大概格式
配置文件中 # 放在行首,用来做注释;
单词之间多余的空格或分隔符会被忽略;
如果文件名包含空格或者其它特殊符号,应当用单引号或者双引号括起来;
配置参数的顺序与混淆结果是没有关系的(不绝对,-injars和-outjars是有先后之分的)
3.配置文件的使用
将配置文件放到需要的包下:
在包中的gradle文件中添加以下脚本:
// An highlighted block
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'net.sf.proguard:proguard-gradle:6.2.2'
}
}
task proguard(type: proguard.gradle.ProGuardTask, dependsOn: jar) {
doFirst {
ext {
injar = rootProject.ext.niagara_home + "\\modules" + "\" + rootProject.name + "-rt.jar"
jar.classifier = "min"
outJar = jar.archivePath
project.configurations.compile*.toURI().findAll().each { item -> libraryjars(item) }
}
injars injar
outjars outJar
configuration 'sensetech.pro'
}
}
在gradle中会生成proguard指令:
4.常用配置规则
这里只列举一下平常Niagara开发中常用的,想要了解更多,请看->这个博客
1.修正为本机rt路径
-libraryjars <java.home>/lib/rt.jar
2.忽略所有警告
-ignorewarnings
3.声明不输出那些未找到的引用和一些错误,继续混淆
-dontwarn
4.不做代码压缩
-dontshrink
5.默认所有目录都会被混淆
-keepdirectories
6.代码优化次数
-optimizationpasses 3
7.混淆的时候大量使用重载,多个方法名使用同一个混淆名,但是他们的方法签名不同
-overloadaggressively
8.所有重新命名过的类都重新打包
-repackageclasses
9.改变作用域:protected,private会变为public
-allowaccessmodification
10.指定不去忽略非公共的库的类的成员
-dontskipnonpubliclibraryclassmembers
11.避免混淆内部类、泛型、异常类
-keepattributes InnerClasses,Signature,Exceptions
12.不混淆某个类的内部类(使用此功能要先有第11条中的内部类的声明)
-keep class cn.com.sensetech.history.service.BSmartHistoryService$* {
*;
}
13.保持所使用NiagaraType注解的类,这里过滤了public 和protected 的变量和方法,只混淆私有的。
-keep,includedescriptorclasses,includecode @javax.baja.nre.annotations.NiagaraType class * {
public <fields>;
public <methods>;
protected <fields>;
protected <methods>;
}
14.保持所有的Servlet
-keep public class * implements javax.servlet.Servlet
15.保持所有接口类。平台中接口类都放到同一包下可使用。
-keep class **.command.** {
<fields>;
<methods>;
}
16.保持所有的实体类。平台中实体类都放到同一包下可使用。
-keep class **.module.** {
<fields>;
<methods>;
}