Proguard 混淆的世界

如果你还没有看过,那真是可惜了,糊里糊涂走了那么久 …

  1. Input/Output Options
  2. Shrinking Options
  3. Optimization Options
  4. Obfuscation Options
  5. Preverification Options
  6. General Options

Input/Output Options

控制输入和输出选项,

Shrinking Options

控制是否删除没有必要的类,默认情况下会删除所有的.class 文件(这时候无法导出jar包,因为jar包是空的),只有被各种 -keep 命令保留的类和相关依赖会保存下来。 可以使用 -printusage [filename] 来打印哪些类(dead code)被删除了, 还可以使用 -whyareyoukeeping class_spec 来查看指定类被保留的原因。Shrink 选项可以删除 类文件中没有使用到的方法或者成员,功能异常强大。

禁用:-dontshrink (默认开启)

Optimization Options

控制如何对 .class 文件进行优化。优化步骤中预定义了许多优化策略,比如:

class/marking/final
	Marks classes as final, whenever possible.
class/unboxing/enum
	Simplifies enum types to integer constants, whenever possible.
class/merging/vertical
	Merges classes vertically in the class hierarchy, whenever possible.
class/merging/horizontal
	Merges classes horizontally in the class hierarchy, whenever possible.
field/removal/writeonly
	Removes write-only fields.
field/marking/private
	Marks fields as private, whenever possible.
...

可以使用 -optimizations 进行细粒度的控制,如果没有十足的把握,最好不要修改这里面的配置。-optimizationpasses n (优化次数) n表示迭代的次数,一般情况下 ~2 次的时候已经会有明显的效果,~10次的时候优化会停止。所以设置 -optimizationpasses 100 并不会优化这么多次,大约10次左右的时候优化就会停止,优化是非常耗 时的过程,Android中默认是 5(据说是因为他们的Team成员老师抱怨build的时间太长了)。 Proguard的优化策略都是很难理解的,如果想吃快餐的话,还是不要琢磨这些 策略了。

禁用:-dontoptimize (默认开启)

Obfuscation Options

终于到了我们关注的地方了,大部分开发者使用Proguard的原因可能都是为了混淆代码,前面的功能只是一些附加的选项。混淆的主要功能是把可读的包名和类名和成员,方法等 替换成a,b,c..等没有任何语义的字符。

class foo {
	public int getFoo()
	public long getFoo()
}

但是在java虚拟机上可以这样使用。

Exceptions, Signature, Deprecated, SourceFile, SourceDir, LineNumberTable, LocalVariableTable, LocalVariableTypeTable, Synthetic, EnclosingMethod, RuntimeVisibleAnnotations, > RuntimeInvisibleAnnotations, RuntimeVisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations, and AnnotationDefault

典型用法,保留堆栈信息

-printmapping out.map

-renamesourcefileattribute SourceFile 		# We're keeping all source file attributes, but we're replacing their values by the string "SourceFile"
-keepattributes SourceFile,LineNumberTable  # We're keeping the line number tables of all methods.

处理类库的时候keep Exceptions, InnerClasses, and Signature attributes, 典型用法见这里

对于一般开发者来说,混淆是最重要的部分,务必理解这里面的每一个配置选项

禁用:-dontobfuscate(默认开启)

Preverification Options

早期版本的jvm标准中对于class文件是运行时验证的,在java>= 6 之后为了加快运行时速度,改为编译时验证。所谓验证时对.class 文件的安全和合法性做一些检查。 可以通过 -dontpreverify 禁用验证。这样可以减少proguard处理时间。对于j2me 版本,需要加上 -microedition 处理上略有差异。

General Options

Shrink,Optimization,Obfuse 是Proguard最重要的主题,General Options 部分是针对Proguard的一些通用配置。

-injars in.jar

-dontshrink
-dontoptimize
-dontobfuscate
-dontpreverify

-dump

至此,Proguard 中比较基础的配置已经介绍完毕,更多,更细节的内容还是看文档吧

*Usage 包含所以可配置属性的说明 *Example 示例脚本,一般性的问题都可以在这里找到现成可用的代码

nTop 10 April 2014
blog comments powered by Disqus