java -jar proguard.jar options ...你可以在ProGuard分布的lib目录下找到ProGuard jar。或者,使用bin目录下包含一些短的Linux和Windows包含命令的脚本。通常,你可以把大多数的选项放在配置文件(例如,myconfig.pro)中,然后调用:
java -jar proguard.jar @myconfig.pro您可以将命令行选项和配置文件中的选项组合起来。例如:
java -jar proguard.jar @myconfig.pro -verbose您可以添加配置文件中的注释,从一个#字符直到行尾。
Short for '-include filename'.-include filename
递归地从给定的filename读取配置-basedirectory directoryname
指定在这些配置参数或此配置文件中所有随后的相关文件名的基本目录-injars class_path
指定应用将要处理的输入jars (or aars, wars, ears, zips, apks, or directories)。在这些jars中的文件将被处理,然后写到输出jars中。默认情况下,任何非类文件将无改变的被复制。请注意任何临时文件(例如,通过IDEs创建的),如果你直接从目录读取文件应特别注意。在类路径中的条目可以被过滤,正如在filters部分解释的一样。为了更好的可读性,类路径条目可以使用多-injars选项指定。-outjars class_path
指定输出jars (or aars, wars, ears, zips, apks, or directories)的名字。额外地,输出条目会被过滤,正如在filters部分(http://proguard.sourceforge.net/manual/usage.html#filefilters)解释的一样。
您必须避免让输出文件覆盖任何输入文件。为了更好的可读性,类路径条目可以使用多-outjars选项指定。没有任何-outjars选项,就没有jars被写。-libraryjars class_path
指定应用将要处理的library jars (or aars, wars, ears, zips, apks, or directories)。在这些jar中的文件将不被包含在输出jars中。指定的库jars至少应该包含从应用类继承的类文件。只被调用的库类文件不需要存在,尽管它们的存在可以提高优化步骤的结果。为了更好的可读性,类路径条目可以使用多-libraryjars选项指定。请注意,当寻找类文件时,为运行ProGuard设置的boot路径和class路径是不考虑寻找的。这意味这你必须明确地指定你的代码将使用的运行jar。尽管这可能看起来麻烦,但它允许你处理指向不同运行环境的应用。例如,你只需指定正确的运行jar,就可以处理J2SE应用(http://proguard.sourceforge.net/manual/examples.html#application)、JME小程序(http://proguard.sourceforge.net/manual/examples.html#midlet)或Android应用(http://proguard.sourceforge.net/manual/examples.html#androidapplication)。-skipnonpubliclibraryclasses
在读library jars的时候指定skip non-public classes可以加速处理并减少ProGuard的内存使用。默认情况下,ProGuard一样地读non-public和public library classes。然而, 如果他们不影响在input jars实际的代码,non-public classes经常是不相关的。忽略他们可以在不影响output时,提升ProGuard速度。不幸的是,一些包含最近JSE运行库的库包含了从public library classes继承的non-public library classes。你不能使用这个选项。如果因为选项设置而找不到类,ProGuard将打印警告。-dontskipnonpubliclibraryclasses
指定不忽略non-public library classes。截止到version 4.5,这是默认设置。-dontskipnonpubliclibraryclassmembers
指定不忽略包可见的库类成员(字段和方法)。默认情况下,ProGuard在解析类库会跳过这些类成员,因为程序类一般不会指向他们。然而,有时,作为库类的程序类存在同一个包中,并且它们确实引用了它们的包可见的类成员。在这种情况下,为了确保处理代码保持一致,实际上读取类的成员是有用的。-keepdirectories [directory_filter]
指定输入jars (or aars, wars, ears, zips, apks, or directories)要被保存的目录。默认情况下,目录项是被删除的。这将减少jar的大小,但是在代码尝试找类似mypackage.MyClass.class.getResource("")的结构时会中断你的程序。你可以通过"-keepdirectories mypackage"保留与包对应的目录。如果这选项不使用filter设定,所有的目录都将保留。设置filter,则只有匹配的目录会保留。例如,"-keepdirectories mydirectory"匹配指定的目录,"-keepdirectories mydirectory/*"匹配它的直接子目录,"-keepdirectories mydirectory/**"匹配它的所有子目录。-target version
指定在处理的类文件中要设置的版本号。版本号可以是1.0, 1.1, 1.2, 1.3, 1.4, 1.5 (或者5), 1.6 (或者6), 1.7 (或者7)或这1.8 (或者8)中的一个。默认情况下,类文件的版本号是保持不变的。例如,你可能想通过改变版本号并预校验来升级类文件到Java 6。您可能不应该降低类文件的版本号,因为代码可能包含旧版本中不支持的结构。-forceprocessing
指定要处理的输入,即使输出似乎是最新的。迄今为止的测试是依据于指定的输入、输出、配置文件或目录的时间。
Keep Options
-keep [,modifier,...] class_specification指定要将类和类成员(字段和方法)保存为您的代码的入口点。例如,为了保持Application,可以指定主类以及其主要方法。为了处理一个library,您应该指定所有可公开访问的元素。-keepclassmembers [,modifier,...] class_specification
如果classes被保留,指定class members被保留。例如,你可能想要保留所有实现Serializable interface的serialization fields and methods of classes。-keepclasseswithmembers [,modifier,...] class_specification
在所有指定的类成员都存在的情况下,指定要被保留的类和类成员。例如,你想要keep all applications that have a main method,没有必要明确地列出他们。-keepnames class_specification
-keep,allowshrinking class_specification的缩写
如果他们没有在Shrinking阶段被移除,指定要保留的类和类成员。例如,你可能想要保留所有实现Serializable interface的所有classes的class names,这样处理代码就可以与原始的serialized classes兼容。不被使用的classes仍然将被移除。只适用于混淆。-keepclassmembernames class_specification
-keepclassmembers,allowshrinking class_specification的缩写
如果类成员没有在收缩阶段移除,指定要保留的类成员。例如,你可能在处理一个被JDK1.2或更老版本编译的库时想要保留class内部类的合成名字。所以混淆器可以在使用处理过的库(尽管ProGuard自己不需要这个库)处理应用时再次检测它们。只适用于混淆。-keepclasseswithmembernames class_specification
-keepclasseswithmembers,allowshrinking class_specification的缩写
在收缩后所有类成员都存在的情况下,指定要保留的类和类成员名。例如,你可能想要保留所有的native方法和其所在的类,以方便处理代码仍然可以和native库代码连接。不使用的native方法仍然可以被移除。如果类被使用了,但其native方法没被使用,则类名仍将被混淆。只适用于混淆。-printseeds [filename]
详尽地列出通过各种-keep选项指定匹配的classes和classes。列表被打印到标准输出或给定的文件。特别在使用通配符时,列表可用于验证是否想要的类成员是否真的被找到。例如,你可能想要列出保留的所有applications和applets。
Shrinking Options
-dontshrink指定不收缩的输入类文件。默认,收缩是被应用的;所有的类和类成员是被移除的,除非被各种-keep选项列出的和被直接或间接依赖的。收缩步骤是被应用在优化步骤之后的,因为一些优化可能移除更多的类和类成员。-printusage [filename]
指定输入类文件的无用代码。该列表被打印到标准输出或给定的文件。例如,你可以列出application中所有未使用的代码。仅适用于收缩。-whyareyoukeeping class_specification
指定打印为什么给定的类和类成员在收缩步骤被keep的细节。如果你想知道为什么某些特定元素在输出中存在,这可能是有用的。通常,可能有许多不同的原因。此选项将为每个指定的类和类成员输出最短链的方法到指定的种子或入口点。在当前的实施过程中,打印出来的最短的链有时会包含循环的不反映实际的收缩过程的扣减。如果-verbose被指定,痕迹将包括所有属性和方法的签名。只适用于收缩阶段。
Optimization Options
-dontoptimize指定不被优化的输入类文件。默认,优化是打开的;所有的方法将在字节码级别被优化。-optimizations optimization_filter
在更细粒度的水平指定优化打开还是关闭。只适用于优化。这是一个专业的选项。-optimizationpasses n
指定要执行的优化通道数量。默认单一通道被执行。多通可能会导致进一步的提高。如果在优化通道后没发现提高,说明优化已结束。只适用于优化。-assumenosideeffects class_specification
指定没有任何的副作用的方法(除了可能有返回值)。在优化阶段,如果知道它的返回值不被使用,ProGuard可以移除这种方法的调用。ProGuard将分析你的程序代码来自动找到这样的方法。它不会分析库代码,因此对这个选项是有用的。例如,你可能指定了方法System.currentTimeMillis(),以至于任何空闲的调用都将被移除。多一些注意的话,你也可以使用选项来移除log代码。注意,ProGuard应用此选项到指定方法的整个层次结构。只适用于优化。通常,假设是危险的;你可以容易地跳出处理代码。如果你知道自己在做什么,才使用此选项。-allowaccessmodification
指定在处理过程中,类和类成员的访问范围可能会扩大。这可以提高优化步骤的结果。例如,当内联一个public getter时,可能必须使访问域也是public。虽然Java的二进制兼容性规范没正式要求这个(cfr. The Java Language Specification, Third Edition, Section 13.4.6),然而一些虚拟机在处理代码时可能有问题。只适用于优化(适用于-repackageclasses选项的混淆)。
禁忌:当处理作为库的代码时,你可能不应该使用这个选项,因为在API中类和类成员没有被设计为public的可能会成为public。-mergeinterfacesaggressively
指定接口可以合并,即使它们的实现类未实现所有接口方法。这可以通过减少总的类的数目来减小输出的大小。注意,Java的二进制兼容性规范允许这样的结构(cfr. The Java Language Specification, Third Edition, Section 13.5.3),即使在在Java语言中不允许(cfr. The Java Language Specification, Third Edition, Section 8.1.4)。只适用于优化。
禁忌:设置此选项可以降低一些JVM的处理代码的性能,因为即时编译倾向于用更少的实现类支持更多接口。糟糕的是,一些JVMs可能无法处理产生的代码。值得注意的是:Sun的JRE 1.3当在一个类中遇到超过256米兰达方法(接口实现类中的方法)可能会抛出一个internalerror。
Obfuscation Options
-dontobfuscate指定不要混淆输入类文件。默认,混淆是被应用的;除了被各种-keep选项列出的,类和类成员会得到一个短的随机的名字。用于调试的内部属性,如源文件名、变量名和行数被删除。-printmapping [filename]
指定为被重命名的类和类成员打印从旧名字到新名字的映射。映射被打印到标准输入或给定的文件。例如,它是后续的增量模糊处理(http://proguard.sourceforge.net/manual/examples.html#incremental)要求的,或如果你想要使得模糊堆栈追踪(http://proguard.sourceforge.net/manual/examples.html#stacktrace)有意义。只适用于混淆。-applymapping filename
指定重用在以前通过ProGuard混淆打印的给定名称的映射。类和类成员被列在得到指定名称的映射文件中。未提及的类和类成员得到新的名称。该映射适用于输入类以及库类。这个选项对于增量混淆是有用的,例如,处理附加或新增到现有代码段的代码。如果代码结构从根本上改变了,ProGuard可以打印出应用映射产生冲突的警告。您可以通过指定选项-useuniqueclassmembernames在混淆运行时降低风险。只允许单一映射文件。只适用于混淆。-obfuscationdictionary filename
指定有所有有效单词的文本文件用于混淆域和方法名。默认,短名字如'a','b'等,被用于作混淆名字。有一个模糊的字典,你可以指定列表中的保留关键字,或使用外来字符的标识符(例如,空格,标点符号,重复词,和#标志的评论)被忽略。注意,模糊字典是很难提高模糊的。好的编译器可以自动更换,而且效果可以相当简单地通过用更简单的名字混淆来撤销。最有用的应用程序是指定通常已经在类文件(如'Code')的字符串,从而减少了一点类文件大小。只适用于混淆。-classobfuscationdictionary filename
指定有所有有效单词的文本文件用于混淆类名。这个模糊字典和选项-obfuscationdictionary是相似的。只适用于混淆。-packageobfuscationdictionary filename
指定有所有有效单词的文本文件用于混淆包名。这个模糊字典和选项-obfuscationdictionary是相似的。只适用于混淆。-overloadaggressively
指定在混淆时用积极地重载。多个域和方法可以使用相同的名字,只要他们被Java字节码(不仅仅是被Java语言要求的参数)要求的参数和返回值不同。这个选项可以使处理程序的代码更小(更不可理解)。只适用于混淆。
禁忌:有Java字节码规范的类文件(cfr.Java虚拟机规范,第二版,4.5节和4.6节的第一个段落),在Java语言是不允许的(cfr.Java语言规范,第三版,第8.3节和第8.4.5节)。有些工具使用的时候会有问题。值得注意的是:
Sun的JDK 1.2.2 javac编译器当编译这样一个库(cfr. Bug #4216736)时产生异常。你可能不应该使用这个选项来处理库。
Sun的JRE 1.4和后来未能序列化重载了原始类型的对象。
Sun的JRE 1.5 pack200工具报告重载的类成员有问题。
类java.lang.reflect.proxy不能处理重载的方法。
-useuniqueclassmembernames谷歌的Dalvik虚拟机不能处理重载的静态域。
指定要分配相同的混淆名字的类成员有相同的名字,不同的名字和模糊的类成员有不同的名字(对于每一个给定的类成员签名)。没有这个选项,更多的类成员可以被映射到相同的短名称,如'a','b'等。因此,这个选项稍微增加所产生的代码大小,但它能确保混淆名称映射可以在后续增量模糊处理步骤中被保留。
例如,考虑两个使用相同的名称和签名的方法的不同的接口。如果没有这个选项,这些方法可以在第一个混淆步骤得到不同的混淆的名称。如果一个补丁加入含有一个实现两个接口的类,ProGuard将要在一个增量模糊处理步骤方法执行相同的方法名称。为了保持生成的代码的一致性,原来的模糊处理的代码要改变。在初始混淆步骤有这个选项,这种重命名将不必要。
这个选项只适用于混淆。事实上,如果你计划执行增量模糊处理,你可能想避免一起收缩和优化,因为这些步骤可以删除或修改部分可能对后续补充是必要的代码。-dontusemixedcaseclassnames
指定在混淆时不产生混合的类名称。默认情况下,混淆类名称可以包括大写字母和小写字母的混合。这可以创建完美地可接受和可用的jars。只有jar在一个不区分大小写的文件系统(例如,Windows)打开时,开箱工具可以让类似命名的类文件互相覆盖。当它打开时,代码自毁!真的想在Windows上打开jar的开发人员可以使用此选项来关闭这种行为。混淆的jar将变得稍大一些。只适用于混淆。-keeppackagenames [package_filter]
指定不要混淆的包名。这个选项过滤器是个逗号分隔的包名列表。包名称可以包含?,*和**通配符,可以被冠以!。只适用于混淆。-flattenpackagehierarchy [package_name]
通过移动他们到单一的给定父包中来重新包装重命名的所有包。没有参数或有个空字符串的包将移到根包中。这个选项是进一步混淆软件包名的例子(http://proguard.sourceforge.net/manual/examples.html#repackaging)。它可以使被处理的代码更小,更不容易理解。只适用于混淆。-repackageclasses [package_name]
通过移动他们到单一的给定包中来重新包装重命名的所有类文件。没有参数或有个空字符串的包将完全移除。这个选项重写了-flattenpackagehierarchy选项。这个选项是进一步混淆软件包名的另一个例子。它可以使被处理的代码更小,更不容易理解。它的废弃名字是-defaultpackage。只适用于混淆。禁忌:如果类移到了其他地方,在其包目录中查找资源文件将不再正常工作。当有疑问时,只要不使用该选项就不会改变了。
指定要保留的任何可选属性。这个属性可以通过一个或多个-keepattributes指令指定。这个选项过滤器是一个逗号分隔的Java虚拟机和ProGuard支持的属性名列表。属性名可以包含?,*和**通配符,可以被冠以!例如,当你处理一个库时,你应该至少保留异常、内部类和签名属性。你也应该保留为产生有用的混淆堆栈追踪的源文件和行数表属性。最后如果你代码依赖于注释的话,你可能想要保留他们。只适用于混淆。-keepparameternames
指定要保存的参数名字和方法类型。这个选项实际上保留调试属性本地变量表和本地变量类型表的修剪版本。在处理库时是有用的。一些IDE可以使用信息帮助使用库的开发者,如工具提示或代码补全。只适用于混淆。-renamesourcefileattribute [string]
指定一个要放在类文件的源文件属性(和源目录属性)的常量字符串。注意属性必须在存在的开始,所以它也必须保持明确使用- keepattributes指令。例如,你可能要处理库和应用程序产生有用的模糊处理的堆栈跟踪。只适用于混淆。-adaptclassstrings [class_filter]
指定应该混淆的类名对应的字符串常量。没有一个过滤器,所有对应于类名称的字符串常量都被改写。有过滤器时,只有在类中的字符串常量匹配过滤器才被改写。例如,如果您的代码中包含一个指向类的大量硬编码字符串,并且您不希望保留它们的名称,您可以使用此选项。主要适用于混淆,虽然相应的类也自动保存在收缩步骤。-adaptresourcefilenames [file_filter]
根据对应类文件(如果存在)的模糊名字,指定要重命名的资源文件。没有过滤器,所有对应于类文件的资源文件被重命名。有过滤器,只重命名匹配文件。例如,看处理资源文件(http://proguard.sourceforge.net/manual/examples.html#resourcefiles)。只适用于混淆。-adaptresourcefilecontents [file_filter]
指定内容将被更新的资源文件。根据对应类文件(如果存在)的模糊名字,任何在资源文件中提到的类名都要重命名。没有过滤器,所有资源文件的内容都更新。有过滤器,只更新匹配的文件。资源文件被解析和适用平台默认的字符集写。你可以通过设置环境变量LANG或者Java系统配置file.encoding来改变默认字符集。例如,看处理资源文件。只适用于混淆。
警告:你可能只是想应用这个选项到文本文件,因为解析和适应作为文本文件的二进制文件,会导致意想不到的问题。因此,确保您指定一个足够窄的筛选器。
Preverification Options
-dontpreverify指定不预校验处理的类文件。默认情况下,如果他们针对Java微型版或Java 6或更高版本,类文件被预校验。对于Java微型版,预校验是被要求的。所以在处理的代码上你要运行额外的预校验时,你需要指定这个选项。对于Java 6,预校验是可选的。但是截止Java 7,它是要求做的。只有当最终针对Android时,它是不必要的,所以你可以关闭它来减少一点处理时间。-microedition
指定针对Java微型版处理的类文件。预校验将添加不同于Java标准版的默认stackmaptable属性的适当的stackmap属性。例如,如果你处理midlets时,你需要这个选项。
General Options
-verbose指定在处理时写出更多的信息。如果程序异常终止,这个选项将打印整个堆栈追踪,而不是只有异常信息。-dontnote [class_filter]
指定不打印配置中的潜在错误或遗漏的记录,如类名中断的错别字或缺失的选项可能是有用的。选项过滤器是一个正则表达式;ProGuard不打印有匹配名字的类的记录。-dontwarn [class_filter]
指定不要警告未解决的引用和其他重要问题。选项过滤器是一个正则表达式;ProGuard不打印有匹配名字的类的警告。忽略警告可能是危险的。例如,如果未解决的类或类成员确实需要处理,这个处理代码将不能正常工作。只有你知道自己在做什么时才使用这个选项。-ignorewarnings
指定打印任何未解决的引用和其他重要问题的警告,但在任何情况下继续处理。忽略警告可能是危险的。例如,如果未解决的类或类成员确实需要处理,这个处理代码将不能正常工作。只有你知道自己在做什么时才使用这个选项。-printconfiguration [filename]
指定要将已解析的整个配置写出来,其中包括文件和替换变量。打印结构到标准输出或指定的文件。对于调试配置,或转换XML配置为更加可读格式有时是有用的。-dump [filename]
指定在任何处理后,将类文件的内部结构写出来。打印结构到标准输出或指定的文件。例如,你可能想要写一个给定的jar文件的内容(http://proguard.sourceforge.net/manual/examples.html#structure),而不需要处理它。
Class Paths
混淆器接受一个泛化的类路径来指定输入文件和输出文件。类路径包含的条目,通过传统的路径分离器(例如,在Unix上的':'或在Windows上的';')分离。。条目的顺序决定了它们的优先级,在重复的情况下。一个类文件或资源文件,
一个apk文件,包含上面的任何一个,
一个jar文件,包含上面的任何一个,
一个AAR文件,包含上面的任何一个,
一个war文件,包含上面的任何一个,
一个ear文件,包含上面的任何一个,
一个zip文件,包含上面的任何一个,
一个目录(结构),包含上面的任何一个。直接指定类文件和资源文件的路径是忽略的,所以类文件一般应是一个jar文件,aar文件,war文件,ear文件,一个zip文件,或目录的一部分。此外,类文件的路径,在档案或目录里不应该有任何的附加目录前缀。
一个apk文件,这类文件和资源文件将被收集。
一个jar文件,在上面,所有的这些都将收集起来,
一个aar文件,在上面,所有的这些都将收集起来,
一个war文件,在上面,所有的这些都将被收集,
一个jar文件,在上面,所有的这些都将被收集起来,
一个zip文件,在上面,所有的这些都将收集起来,
一个目录,在上面,所有的这些都将收集起来。写输出项时,ProGuard一般会用一个合理的方式包装结果,正如需要一样重建输入条目。把所有的东西写在输出目录是最直接的选择:输出目录将包含一个完整的输入条目的重建。包装可以是几乎任意复杂的:你可以处理一个完整的应用程序,连同它的文档打包在一个压缩文件,再次作为一个压缩文件写出它。实例部分显示了重构输出档案(http://proguard.sourceforge.net/manual/examples.html#restructuring)的几种方法。
对遇到的所有aar名称的过滤器,
对遇到的所有apk名称的过滤器,
对遇到的所有zip名称的过滤器,
对遇到的所有ear名称的过滤器,
对遇到的所有war名称的过滤器,
对遇到的所有jar名称的过滤器,
对遇到的所有类文件和资源文件名称的过滤器。如果指定少于7个过滤器,它们被假定为后者的过滤器。任何空滤器都被忽略。更正式地,一个过滤的类路径条目看起来像这样:
classpathentry([[[[[[aarfilter;]apkfilter;]zipfilter;]earfilter;]warfilter;]jarfilter;]filefilter)方括号“[]”意味着它们的内容是可选的。
File Names
ProGuard接受不同的文件名和目录名的绝对路径和相对路径。一个相对路径被解释为如下:相对于基本目录,如果设置,或其他
相对于所指定的配置文件,如果有的话,或其他
相对于工作目录。名称可以包含Java系统属性(或Ant属性,当使用Ant时),用角括号分隔,“<”和“>”。属性被其相应的值自动替换。
File Filters
像普通的filters,file filter是一个逗号分隔的可以包含通配符的文件名列表。仅仅有匹配文件名的文件被读(在input jars情况下), 或写(在output jars情况下)。支持下面的通配符:
?匹配文件名中的任何单个字符。
* 匹配不包含目录分隔符的文件名的任何部分。
例如,“java/**.class,javax/**.class”匹配所有在java和javax中的类文件。**匹配可能包含任意数量的目录分隔符的文件名的任何部分。
Filters
ProGuard用过滤器为许多不同方面的配置提供选项:文件、目录、类、包、属性、优化器名称等等。?匹配文件名中的任何单个字符。
* 匹配不包含包或目录分隔符的名称的任何部分。
**匹配可能包含任意数量的包或目录分隔符的名称的任何部分。例如,"foo,*bar"匹配foo和所有以bar结尾的名称。
Overview of Keep Options
各种保持萎缩和混淆的选项可能看起来有点混乱,但实际上在他们背后有一种模式。下表总结了它们是如何相关的:
Keep From being removed or renamed From being renamed
Classes and class members -keep -keepnames
Class members only -keepclassmembers -keepclassmembernames
Classes and class members, if class members present -keepclasseswithmembers -keepclasseswithmembernames这些选项的每一个都遵循着类和类的成员(字段和方法)应该被应用的规范。
Keep Option Modifiers
includedescriptorclasses指定在方法和字段的类型描述符中使用了-keep的任何类都应该保留。当保持原生方法名称,为了确保native方法的参数类名不被重命名,这通常是有用的。他们的签名,保持完全不变,并兼容原生库。allowshrinking
指定在-keep选项中指定的入口点可能会收缩,即使它们必须保留。那就是,入口点可以在收缩步骤删除,但是如果他们是必要的,他们可能不被优化和混淆。allowoptimization
指定在-keep选项中指定的入口点可能会优化,即使它们必须保留。那是,入口点可以在优化步骤中改变,但他们可能不会被删除或混淆。此修饰符仅用于实现不寻常的要求。allowobfuscation
指定在-keep选项中指定的入口点可能会混淆,即使它们必须保留。那是,入口点可以在混淆步骤重命名,但他们可能不会被删除或优化。此修饰符仅用于实现不寻常的要求。
Class Specifications
类规范是类和类成员(字段和方法)的模板。它是用在各种保存选项和assumenosideeffects选项。对应的选项仅适用于模板匹配的类和类成员。
[@annotationtype] [[!]public|final|abstract|@ ...] [!]interface|class|enum classname
[extends|implements [@annotationtype] classname]
[{
(fieldtype fieldname);[@annotationtype] [[!]public|private|protected|static|volatile|transient ...] <fields> |
<init>(argumenttype,...) |[@annotationtype] [[!]public|private|protected|static|synchronized|native|abstract|strictfp ...] <methods> |
classname(argumenttype,...) |
(returntype methodname(argumenttype,...));
[@annotationtype] [[!]public|private|protected|static ... ] *;
...
}]
方括号"[]"意味着他们的内容是可选的。省略号“……”意味着任何数量的前面项目可能被指定。竖线“|”分隔两种选择。非圆括号仅仅组合部分属于一起的规格。缩进试图澄清预期的意思,但在实际的配置文件中的空白是不相关的。
类关键字是指任何接口或类。接口关键字限制匹配接口类。关键字enum限制匹配枚举类。前面的接口或枚举关键词的!分别限制为不是接口或枚举类。
每个类名称必须是完全限定的,如java.lang.String。内部类之间用一个美元符号“$”,如java.lang.Thread$State。类名可以指定包含以下通配符的正则表达式:
?在一个类名称中匹配任何单个字符,但不是包分隔符。例如,"mypackage.Test?"匹配"mypackage.Test1"和"mypackage.Test2", 但不匹配"mypackage.Test12"。
*匹配一个类名称的任何部分,不包含包分隔符。例如,"mypackage.*Test*"匹配"mypackage.Test"和"mypackage.YourTestApplication", 但不匹配 "mypackage.mysubpackage.MyTest"。或者更普遍的是, "mypackage.*"匹配在"mypackage"中的所有类,但不匹配在它子包中的类。
**匹配任何一个类名称的任何部分,可能包含任意数量的包分隔符。例如,"**.Test"匹配所有的测试类,除了根包。或者,“mypackage.**”匹配在“mypackage”及其子包中所有的类。
对于附加的灵活性,类名称可以实际上是逗号分隔的类名称的列表,与可选!,如文件名过滤器。这个符号看起来不像是Java,所以应该用适度的。
为了方便和向后兼容,类名称*指任何类,不论其包。
extends和implements规范通常被用来限制类通配符。它们是当前等价的,指定只类扩展或实现给定的类限定。请注意,给定的类本身不包含在这个集合中。如果需要,则应在一个单独的选项中指定。
@规范可以用来限制类和类的成员,这些成员的注释与指定的注释类型。一个annotationtype指定类名一样。
域和方法是就像在Java指定的一样,但方法参数列表不包含参数的名称(就像在其他类似的工具javadoc和javap)。规格也可以包含以下捕捉所有通配符:
<init> matches any constructor.
<fields> matches any field.
<methods> matches any method.
* matches any field or method.
注意上面的通配符都没有返回类型,只有<init>有参数列表。
属性和方法可能用正则表达式指定。名字可包含下面通配符:
?匹配方法名中的任何单个字符。
*匹配方法名称的任何部分。
类型的描述符可以包含通配符:
%匹配任何原始类型("boolean", "int", etc, but not "void")。
?在类名称中匹配任何单个字符。
*匹配一个类名称的任何部分,不包含包分隔符。
**匹配任何一个类名称的任何部分,可能包含任意数量的包分隔符。
***匹配任何类型(原始的或非原始的,数组或非数组)。
...匹配任何类型的任何数量的参数。
注意:?,*,和**通配符不会匹配原始类型。此外,只有***通配符匹配数组类型的任何尺寸。例如,"** get*()"匹配"java.lang.Object getObject()",但不匹配"float getFloat()",也不匹配"java.lang.Object[] getObjects()"。
构造器可以用短类名(不包括包名)或使用全类名指定。就像在Java语言中,构造器有参数列表,但没返回值。
类的访问修饰符和类成员访问修饰符通常用于限制通配的类和类成员。他们指定要为成员设置相应的访问标志。前面的!指定相应的访问标志未设置。
结合多个标志是允许的(例如,public static)。这意味着,是访问标志被设置(例如public static),除了当他们是相互矛盾的,在这种情况下,其中至少有一个已经被设置(例如至少public或protected)。
ProGuard支持额外的修饰符synthetic(合成), bridge, and varargs,这些可能被编译器设置。