ProGuard惯用法

运行Proguard,立即输入(当然你需要定位到proguard.jar的目录下面):

java -jar proguard.jar options …

proguard.jar在lib目录下(android的sdk下/tools/proguard可以找到),而bin目录下有了一些linux和windows脚本可以执行这个命令。典型的,你可以把选项都放在一个文件里(比如说myconfig.pro),那就只需要这样:

java -jar proguard.jar @myconfig.pro

你可以组合命令行选项和配置文件选项,比如:

java -jar proguard.jar @myconfig.pro -verbose

添加注释使用的是#,可以注释掉一行

文字与分隔符之间的空格会被忽略掉,文件名包含空格或者特殊字符用单引号或双引号引用。选项可以由命令行中的参数或配置文件中的命令行任意组合,比如:你可以引用任意的命令行选项部分来避免特殊字符的shell扩展。

选项的顺序通常是无关紧要的,为了简洁明了,你可以用它们第一个独特的字母来替代。

Input/Output Options

Keep Options

Shrinking Options

Optimization Options

Obfuscation Options

Preverification Options

General Options

Class Paths

File Names

File Filters

Filters

Overview of Keep Options

Keep Option Modifiers

Class Specifications

Input/Output Options

@filename 是’-include filename’简写

-include filename

从给定的文件名中递归的读取配置选项

-basedirectory directoryname

为在这些配置参数里面的后续的相对文件名或这些配置文件指定一个目录。

-injars class_path

指定应用程序的要处理的jars(or wars, ears, zips, or directories)路径,这些jar里面的class文件将被处理和写入到输出jar中。默认的,所有的没有包含.class的文件将会被原风不动的复制,请注意任何临时文件,特别是你直接从目录里导入文件。class路径中的条目会像filters描述的那样被过滤掉。为了更好的可读性,可以使用多个指定的类路径条目 -injars 选项。

-outjars class_path

指定处理完后要输出的jar,war,ear和目录的名称 ,在先前-injars 输入的文件将会被重写到指定的jar中,这将允许你选择输入的jar到指定输出的jar。另外,输出条目可以按filters的规则过滤掉,每一个被处理过的class文件和资源文件会被写入到第一个匹配过滤规则的输入文件中。

你必须避免让输出文件重写任何的输入文件中。为了更好的可读性,可以使用多个类路径条目 -outjars选项,如果没有任何的-outjars 选项,将没有jar会被重写。

-libraryjars class_path

指定要程序所引用的 jar(比如jdk的rt.jar)( 或 war, ears,zips,或者目录)。这些jar里面的文件不会输入到输出jar中,指定的library jars 至少包含application的子类。Library class files 只被调用而不必呈现,虽然它们的存在可以提升优化的结果,这些class路径会filter的要求来过滤。为了更好的可读性,可以使用多个类路径条目 -libraryjars选项。

请注意当寻找library class 时,引导路径和progurad的运行路径是不会被考虑在内的,这就意味着你要明确地指出你的代码会用到的run-time jar。虽然这会看起来比较笨重,但是它允许你运行自己的程序在不同的运行时环境中。比如,你可以通过指定合适的run-time jar就可以运行J2SE applications和JME midlets。

-skipnonpubliclibraryclasses

为了加快运行和减少proguard的使用内存,当读取library jars指定跳过non-public 类。在默认情况下ProGuard读取non-public 和public类一样,然而,如果它们没有影响输入jar里面的的程序代码,non-public 类通常是不相关的。在没有影响输出的情况下,忽略它们来加速Proguard.不幸的是,一些库,包括最近 的JSE run-time 库,包含一些非public class继承自公共的library classes,那在这种情况下你不能使用这个option。在使用这个选项ProGuard将打印出警告当找不到类的时候。

-dontskipnonpubliclibraryclasses

指定不去忽略非公共库类,在4.5以上这个是默认设置。

-dontskipnonpubliclibraryclassmembers

指定不忽略包可见的库类成员(字段和方法)。默认地,当解析库类的时候ProGuard会跳过这些类成员,项目类一般不会去引用它们。然而有的时候,程序里的类相当于库类存在于相同包。此时它们会引用他们的包可见的类成员。在这种情况下为了保持程序代码保持一致性去读取这些类的成员是有用的。

-keepdirectories [directory_filter]

指定要保存在输出jars(或wars ,ears,或directories)的目录。默认地,目录部分是会被移除的,这样可以减少jar的大小,但是当程序尝试用构造器找寻它们时会出现不愿看见的结果比如:“MyClass.class.getResource(“”)”如果这个选项没过滤器,所有的目录都会保存下来,有过滤器时只有符合过滤器的目录会保存下来。

-target version

在被处理的class文件中指定版本号。版本号可以是1.0,1.1,1.2,1.3,1.4,1.5(或者就是5),1.6(或者就是6),1.7(或者就是7),默认地,class文件的版本号是保持不变的。比如,你可能想更新class file到Java 6,通过改变他们的版本让他们预编译。

-forceprocessing

指定输入的过程,即使输出看起来最新。这个最新的测试是基于比较指定输入,输出和配置文件或目录的时间戳。

Keep Options

-keep [,modifier,…] class_specification

保护指定对象不被混淆,指定类和类成员(变量和方法)将被保存为程序的入口。比如,为了keep an application,你可以单独指定主类和它的主方法。为了处理库,你应该指定所有公开的元素。

e.g:

-keep public class mypackage.MyMain {

public static void main(java.lang.String[]);

}

-keepclassmembers [,modifier,…] class_specification

指定不被混淆的类成员,如果它们的类也被保护了它们会被保护的更好。比如你想保护可以序列化类的变量和方法。

-keepclassmembers class * implements java.io.Serializable {

private static final java.io.ObjectStreamField[] serialPersistentFields;

private void writeObject(java.io.ObjectOutputStream);

private void readObject(java.io.ObjectInputStream);

java.lang.Object writeReplace();

java.lang.Object readResolve();

}

-keepclasseswithmembers [,modifier,…] class_specification

保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。比如,你想保持似有的包含主方法 的application而无需显示的列出它们。

-keepclasseswithmembers public class * {

public static void main(java.lang.String[]);

}

-keepnames class_specification

是-keep,allowshrinking class_specification的缩写

保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除)

keepclassmembernames class_specification

相当于-keepclassmembers,allowshrinking class_specification

只保留成员名称,混淆内容

keepclasseswithmembernames class_specification

相当于-keepclasseswithmembers,allowshrinking class_specification

如果这些指定的类在压缩阶段后存在, 保护指定的类和类的成员的名称。

保持 native 方法不被混淆:

-keepclasseswithmembernames class * {

native <methods>;

}

-printseeds [filename]

列出匹配各种-keep选项的类和类的成员,标准输出到给定的文件。

Shrinking Options

-dontshrink

产压缩输入类文件,默认是要压缩的,除了-keep列出的class和这些类文件直接或间接引用的文件间外其它类文件都会被移除,压缩步骤在优化之后执行,因为优化可能会移除更多的类文件和类成员。

-printusage [filename]

指定输入文件中的死代码输出到标准文件中,适用于使用了压缩。

-whyareyoukeeping class_specification

打印出为什么在压缩过程中保留了这些类文件和类成员的具体原因,也适用了使用了压缩的情况。

Optimization Options

-dontoptimize

指定不优化输入class文件,优化功能默认是开启的,所有的方法在字节级被优化。、

-optimizations optimization_filter

指定优化是可用还是禁止,这个是一个更加精细的选项,只有当优化时适用。这是一个专业的选项。

-optimizationpasses n

指定代码进行迭代优化的次数,在Android里面默认是5,这条指令也只有在可以优化时起作用。

-allowaccessmodification

优化时允许访问并修改有修饰符的类和类的成员,这可以提高优化步骤的结果。比如,当内联一个公共的getter方法时,这也可能需要外地公共访问。虽然java二进制规范不需要这个,要不然有的虚拟机处理这些代码会有问题。当有优化和使用-repackageclasses时才适用。

指示语:不能用这个指令处理库中的代码,因为有的类和类成员没有设计成public ,而在api中可能变成public

-mergeinterfacesaggressively

指定接口可以合并,即使实现类没实现所有的方法。该选项可以通过减少类的总数减少输出文件的大小。只有开启优化时可用。

Obfuscation Options

-dontobfuscate

指定不混淆类文件,默认开启。

-printmapping [filename]

输出类和类成员新旧名字之间的映射到指定文件中。只有开启混淆时可用。

-applymapping filename

重用映射,映射文件未列出的类和类成员会使用随机的名称。如果代码结构从根本上发生变化,ProGuard 可能会输出映射会引起冲突警告。你可以通过添加-useuniqueclassmembernames选项来降低风险。只能指定一个映射文件。只有开启混淆时可用。

-obfuscationdictionary filename

使用文件中的关键字作为方法及字段混淆后的名称。默认使用 ‘a’,’b’ 等短名称作为混淆后的名称。你可以指定保留关键字或不相关的标识符。文件中的空格、标点符号、重复的单词及注释会被忽略。只有开启混淆时可用。

-classobfuscationdictionary filename

使用文件中的关键字作为类混淆后的名称,类似于-obfuscationdictionary。只有开启混淆时可用。

-packageobfuscationdictionary filename

使用文件中的关键字作为包混淆后的名称,类似于-obfuscationdictionary。只有开启混淆时可用。

-overloadaggressively

开启侵入性重载混淆。多个字段及方法允许同名,只要它们的参数及返回值类型不同。该选项可使处理后的代码更小(及更难阅读)。只有开启混淆时可用。

注:Dalvik 不能处理重载的静态字段

-useuniqueclassmembernames

方法同名混淆后亦同名,方法不同名混淆后亦不同名。不使用该选项时,类成员可被映射到相同的名称。因此该选项会增加些许输出文件的大小。只有开启混淆时可用。

-dontusemixedcaseclassnames

混淆时不会产生大小写混合的类名。默认混淆后的类名可以包含大写及小写。如果 jar 被解压到非大小写敏感的系统(比如 Windows),解压工具可能会将命名类似的文件覆盖另一个文件。只有开启混淆时可用。

-keeppackagenames [package_filter]

不混淆指定的包名。过滤器是由逗号分隔的包名列表。包名可以包含 ?、、* 通配符,并且可以在包名前加上 ! 否定符。只有开启混淆时可用。

-flattenpackagehierarchy [package_name]

重新打包所有重命名的包到给定的包中。如果没参数或字符串为空,包移动到根包下。该选项是进一步混淆包名的例子,可以使处理后的代码更小更难阅读。只有开启混淆时可用。

-repackageclasses [package_name]

重新打包所有重命名的类到给定的包中。如果没参数或字符串为空,类的包会被完全移除。该选项覆盖-flattenpackagehierarchy,是进一步混淆包名的另一个例子,可以使处理后的代码更小更难阅读。曾用名为-defaultpackage。只有开启混淆时可用。

-keepattributes [attribute_filter]

保留任何可选属性。过滤器是由逗号分隔的 JVM 及 ProGuard 支持的属性列表。属性名可以包含 ?、、* 通配符,并且可以在属性名前加上 ! 否定符。例如:处理库文件时应该加上Exceptions,InnerClasses,Signature属性。同时保留SourceFile及LineNumberTable属性使混淆后仍能获取准确的堆栈信息。同时如果你的代码有使用注解你可能会保留annotations属性。只有开启混淆时可用。

-keepparameternames

保留已保留方法的参数的名称及类型。只有开启混淆时可用。

-renamesourcefileattribute [string]

指定一个常量字符串作为SourceFile(和SourceDir)属性的值。需要被-keepattributes选项指定保留。只有开启混淆时可用。

-adaptclassstrings [class_filter]

混淆与完整类名一致的字符串。没指定过滤器时,所有符合现有类的完整类名的字符串常量均会混淆。只有开启混淆时可用。

-adaptresourcefilenames [file_filter]

以混淆后的类文件作为样本重命名指定的源文件。没指定过滤器时,所有源文件都会重命名。只有开启混淆时可用。

-adaptresourcefilecontents [file_filter]

以混淆后的类文件作为样本混淆指定的源文件中与完整类名一致的内容。没指定过滤器时,所有源文件中与完整类名一致的内容均会混淆。只有开启混淆时可用。

Preverification Options

-dontpreverify

指定不对处理后的类文件进行预校验。默认情况下如果类文件的目标平台是 Java Micro Edition 或 Java 6 或更高时会进行预校验。目标平台是 Android 时没必要开启,关闭可减少处理时间。

-microedition

指定处理后的类文件目标平台是 Java Micro Edition。

General Options

-verbose

指定处理期间打印更多相关信息。

-dontnote [class_filter]

指定配置中潜在错误或遗漏时不打印相关信息。类名错误或遗漏选项时这些信息可能会比较有用。class_filter 是一个可选的正则表达式。类名匹配时 ProGuard 不会输出这些类的相关信息。

-dontwarn [class_filter]

指定找不到引用或其他重要问题时不打印警告信息。class_filter 是一个可选的正则表达式。类名匹配时 ProGuard 不会输出这些类的相关信息。

注意:如果找不到引用的类或方法在处理过程中是必须的,处理后的代码将会无法正常运行。请明确该操作的影响时使用该选项。

-ignorewarnings

打印找不到引用或其他重要问题的警告信息,但继续处理代码。

注意:如果找不到引用的类或方法在处理过程中是必须的,处理后的代码将会无法正常运行。请明确该操作的影响时使用该选项。

-printconfiguration [filename]

将已解析过的配置标准输出到指定的文件。该选项可用于调试配置。

-dump [filename]

标准输出类文件的内部结构到给定的文件中。例如,你可能要输出一个 jar 文件的内容而不需要进行任何处理。

时间: 2025-01-01 11:17:53

ProGuard惯用法的相关文章

python字符编码惯用法

本文总结在实际应用中遇到的python字符编码问题,制定一套编码相关的约定,避免编码上的错误. 在写猥琐宝典时需要总结soj上做过的题,准备在总结过程中顺便写一个soj上的题解.题解使用python可读,也就是python可以直接eval的格式,以便于处理.写题解老是copy soj上的题目id,title不是太方便,所以就准备自动生成一个空的题解,里面包含了我做过的题.然而直接从soj上只能拿到自己过了的题的id列表,缺乏其它信息.缺乏的信息可以抽象为soj数据库,其中包含了一个以id为主键的

RAII惯用法:C++资源管理的利器

原文出处:http://www.cnblogs.com/hsinwang/articles/214663.html RAII是指C++语言中的一个惯用法(idiom),它是"Resource Acquisition Is Initialization"的首字母缩写.中文可将其翻译为"资源获取就是初始化".虽然从某种程度上说这个名称并没有体现出该惯性法的本质精神,但是作为标准C++资源管理的关键技术,RAII早已在C++社群中深入人心. 我记得第一次学到RAII惯用法

RAII惯用法

RAII,也称为“资源获取就是初始化”,是c++等编程语言常用的管理资源.避免内存泄露的方法.简单的说,RAII 的做法是使用一个对象,在其构造时获取资源,在对象生命期控制对资源的访问使之始终保持有效,最后在对象析构的时候释放资源. 例如,我们无需直接调用一对非成员函数OpenPort/ClosePort,而是可以考虑定义常性且内部初始化的RAII概念的“端口”操作类: class Port{ public: Port(const string& destination);//调用OpenPor

Kotlin语言的惯用法

空语句 Kotlin 语言中的空语句有 {} Unit when (x) { 1 -> ... 2 -> ... else -> {} // else -> Unit } 原文地址:https://www.cnblogs.com/zwvista/p/8452388.html

《编写高质量代码 改善python程序的91个建议》第二章 惯用法 8-18

建议8:调试语句assert expression, "sentence", python -O xx.py 可以禁用断言,建议少用断言: 建议9:数据交换不推荐使用中间值 语句执行时间: from timeit import Timer Timer('x,y = y,x').timeit() ## x,y = y,x 相当于元组(x,y)= (y,x) 涉及packing和unpacking def swap() x = 2 y = 3 x,y = y,x import disdis

extern &quot;C&quot;的用法解析(转)

原文链接:http://www.cnblogs.com/rollenholt/archive/2012/03/20/2409046.html 1.引言 C++语言的创建初衷是“a better C”,但是这并不意味着C++中类似C语言的全局变量和函数所采用的编译和连接方式与C语言完全相同.作为一种欲与C兼容的语言, C++保留了一部分过程式语言的特点(被世人称为“不彻底地面向对象”),因而它可以定义不属于任何类的全局变量和函数.但是,C++毕竟是一种面向对象的程序设计语言 ,为了支持函数的重载,

转:extern &quot;C&quot;的用法解析

1.引言 C++语言的创建初衷是“a better C”,但是这并不意味着C++中类似C语言的全局变量和函数所采用的编译和连接方式与C语言完全相同.作为一种欲与C兼容的语言, C++保留了一部分过程式语言的特点(被世人称为“不彻底地面向对象”),因而它可以定义不属于任何类的全局变量和函数.但是,C++毕竟是一种面向对象的程序设计语言 ,为了支持函数的重载,C++对全局函数的处理方式与C有明显的不同. 2.从标准头文件说起 某企业曾经给出如下的一道面试题: 面试题 为什么标准头文件都有类似以下的结

细说 ASP.NET Cache 及其高级用法

许多做过程序性能优化的人,或者关注过程程序性能的人,应该都使用过各类缓存技术. 而我今天所说的Cache是专指ASP.NET的Cache,我们可以使用HttpRuntime.Cache访问到的那个Cache,而不是其它的缓存技术. 以前我在[我心目中的Asp.net核心对象] 这篇博客中简单地提过它,今天我打算为它写篇专题博客,专门来谈谈它,因为它实在是太重要了.在这篇博客中, 我不仅要介绍它的一些常见用法,还将介绍它的一些高级用法. 在上篇博客[在.net中读写config文件的各种方法] 的

extern &quot;C&quot; 的用法解析

1.引言 C++语言的创建初衷是"a better C",但是这并不意味着C++中类似C语言的全局变量和函数所采用的编译和连接方式与C语言完全相同.作为一种欲与C兼容的语言, C++保留了一部分过程式语言的特点(被世人称为"不彻底地面向对象"),因而它可以定义不属于任何类的全局变量和函数.但是,C++毕竟是一种面向对象的程序设计语言 ,为了支持函数的重载,C++对全局函数的处理方式与C有明显的不同. 2.从标准头文件说起 某企业曾经给出如下的一道面试题: 面试题 为