ProGuard 使用说明
本文主要是翻译proguad的官方文档,以便以后使用的时候不需要再次去看英文,每次写proguard总是那么痛苦,必须写个博客记录一下,有些地方的意思我也不懂,有注明原文!!
什么是proguard
proguard是一个用于对代码进行瘦身,优化,混淆的java类库,可以把没有用到的方法,变量,属性等自动移除,经过proguad处理的app,size会更小,运行更快,还可以增加反编译的难度。
典型应用
- 减少android app的size,加快启动速度
- 优化移动应用的代码,提升性能
- 保护app不被反编译和篡改
proguard相比于其他java混淆工具的主要优势是基于模板的配置(原文:compact template-based configuration)。一条简单的命令就可以很有用。
proguard是一个命令行工具,也有图形界面使用,还可以以插件的形式加入的ant,gradle等,它已经是android sdk的一部分,只需要简单的配置就可以开启(这点开发过android的苦逼都应该知道)。
proguad 使用代码混淆来提供对反编译的基本支持。但是还是可以被反编译。如果需要深度的保护,需要使用 DexGuard。 DexGuard可以对app进行优化,混淆,还可以对string,classes,resource,resource files, asset files, and native libraries进行加密(看上去很牛逼的样子,还没有用过)
使用
进入正题,接下来学习各个命令的使用
运行proguard
java -jar proguard.jar options ...
可以在proguard发布包的lib目录下找到jar,也可以使用bin目录下的脚本来运行,一般情况下可以把参数写在 myconfig.pro中,然后运行
java -jar proguard.jar @myconfig.pro
也可以把脚本和参数合起来使用
java -jar proguard.jar @myconfig.pro -verbose
一个配置文件可以如下:
-injars myapplication.jar
-outjars myapplication_out.jar
-libraryjars <java.home>/lib/rt.jar
-printmapping myapplication.map
-keep public class mypackage.MyMain {
public static void main(java.lang.String[]);
}
接下来介绍各个参数
注:关于filename,class_path,filter的写法后面有解释
Input/Output Options
-include filename
递归的从给定文件中读取参数
-basedirectory directoryname
指定当前配置文件中所有路径参数的基本目录
-injars class_path
指定需要被处理r的jar(或者 aars, wars, ears, zips, apks, or directories)。在默认情况下任何非.class的文件会被原样复制到最终打包的jar。这里需要注意的是那些临时文件(如IDE产生的文件),尤其是当你直接用一个目录指定jar文件。class_path下的条目可以被过滤,详细请看filter,为了可读性,可以使用多条-injars命令
-outjars class_path
指定输出jar包的名字(或者 aars, wars, ears, zips, apks, or directories)。前面-injars 指定的jar包会被包含到输出jar包里。这个也可以使用过滤,详细请看filter,
你必须避免让输出文件复写输入文件。为了可读性,可以使用多条-outjars ,如果没有指定-outjar,不会有任何jar包生成。
-libraryjars class_path
指定要被处理的程序依赖的jar(或者 aars, wars, ears, zips, apks, or directories),这些jar不会被包进output jar。这个指定的jar至少得包含程序中有被继承的类。那些只有被调用的库中的class文件不需要出现,虽然他们的出现会改善优化的结果(什么鬼, Library class files that are only called needn’t be present, although their presence can improve the results of the optimization step. )。当然这些path也是可以过滤的 ,为了可读性,可以使用多条 -libraryjars options.
请注意那些为运行proguard设置的class path,不会被用于寻找类文件,也就是说你必须显示的指定你的代码需要用到的jar路径。虽然这看上去有点麻烦,但是可以让你处理不同运行环境下的程序。比如你可以处理
j2se 的程序也可以处理android app,只要你指定合适的jar路径。
示例:
-injars myapplication.jar
-outjars myapplication_out.jar
-libraryjars <java.home>/lib/rt.jar
-printmapping myapplication.map
-keep public class mypackage.MyMain {
public static void main(java.lang.String[]);
}
-skipnonpubliclibraryclasses
在读取依赖的库文件时,略过非public类,来加快处理速度和减少ProGuard内存消耗 。
-dontskipnonpubliclibraryclasses
在读取依赖的库文件时,不要略过那些非public类,在4.5版本中,这是默认设置
-dontskipnonpubliclibraryclassmembers
不要忽略依赖库中的非公有的类成员,包括域和方法,proguard默认会忽略
-keepdirectories [directory_filter]
指定那些需要被保留在输出jar的文件目录,在默认情况下,这些目录会被移除来减小输出文件的size。
-target version
指定需要被处理的类文件的java版本,如1.0, 1.1, 1.2, 1.3, 1.4, 1.5 (or just 5), 1.6 (or just 6), 1.7 (or just 7), or 1.8 (or just 8)
-keep 选项
指定需要被保留的类和成员。
-keepclassmembers
指定需要被保留的类成员,如果他们的类也有被保留。比如你要保留一个序列化类中的所有成员和方法
-keepclasseswithmembers
指定保留那些含有指定类成员的类,比如你想保留所有包含main方法的类
-keepnames
指定那些需要被保留名字的类和类成员,前提是他们在被代码压缩的时候没有被移除。举个栗子,你可能希望保留那些实现了Serializable接口的类的名字
-keepclassmembernames
指定那些希望被保留的类成员的名字
<