2 Keep 选项 keep选项是为了在代码混淆的过程中保留部分类及其字段不被混淆以满足程序运行需求。keep选项一共有如下6种规则:
keep
keepnames
keepclassmember
keepclassmembernames
keepclasseswithmembers
keepclasseswithmembernames
2.1 keep
-keep
[,modifier,…] class_specification
Specifies classes and class members (fields and methods) to be preserved as entry points to your code. For example, in order to keep an application, you can specify the main class along with its main method. In order to process a library, you should specify all publicly accessible elements.
keep规则用于标识程序入口,被keep规则修饰的类及其成员会被指定为程序入口,从而免于被混淆。
2.2 keepnames 被keepnames修饰的类及其成员不会被混淆,但前提是对应的成员在shrinking类没有被删减掉。比如保留所有实现Serializable接口的类名:
-keepnames class * implements java.io.Serializable 1 2.3 keepclassmembers keepclassmembers仅保留指定的类成员不被混淆,但类名会被混淆。接着上面的例子,如果我们不仅向保留所有实现Seriablizable接口的类名,同时还要保留其所有的接口方法:
-keepnames class * implements java.io.Serializable
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
2.4 keepclassmembernames keepclassmembernames保留指定类成员不被混淆,前提是相关的类成员没有在shrinking阶段被删减。
-keepclasseswithmembers
[,modifier,…] class_specification
Specifies classes and class members to be preserved, on the condition that all of the specified class members are present. For example, you may want to keep all applications that have a main method, without having to list them explicitly.
保留类和类成员不被混淆,前提是对应的类包含所有指定的类成员。适用于指定一批拥有功能类成员的方法,而不用一一列举。比如保留所有又main方法的类:
-keepclasseswithmembers public class * {
public static void main(java.lang.String[]);
}
2.6 keepclasswithmembernames keepclasseswithmembernames保留类和类成员不被混淆,前提是对应的类包含所有指定的类成员,同时对应的类成员在shrinking阶段没有被删减。比如保留所有native方法:
-keepclasseswithmembernames class * {
native <methods>;
}
2.7 关系梳理 看完上述几个规则一定有点晕,没有关系,记住下面这个表就是:
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规则都应该跟一个类说明(specification of classes and class members)。如下就是一个类说明的例子:
class * {
native <methods>;
}
类说明的规则将在下一节详细介绍。
如果你不清楚到底该用哪个keep规则,建议直接使用keep,被keep标明的类及其类成员不会被删减或重命名。需要注意的是,如果仅仅指明要keep的类,而不指明其类成员:
keep class yourpackage.demo 1 那ProGuard仅会保留其类和无参数构造方法不被删减或重命名。
-dontwarn
[class_filter]
Specifies not to warn about unresolved references and other important problems at all. The optional filter is a regular expression; ProGuard doesn’t print warnings about classes with matching names. Ignoring warnings can be dangerous. For instance, if the unresolved classes or class members are indeed required for processing, the processed code will not function properly. Only use this option if you know what you’re doing!
译文:指定根本不警告未解决的引用和其他重要问题。可选的过滤器是正则表达式; ProGuard 不会打印有关具有匹配名称的类的警告。忽视警告可能会很危险。例如,如果确实需要处理未解析的类或类成员,则处理后的代码将无法正常运行。 仅当您知道自己在做什么时才使用此选项!
-repackageclasses
[package_name]
Specifies to repackage all class files that are renamed, by moving them into the single given package. Without argument or with an empty string (’’), the package is removed completely. This option overrides the -flattenpackagehierarchy
option. It is another example of further obfuscating package names. It can make the processed code even smaller and less comprehensible. Its deprecated name is -defaultpackage
. Only applicable when obfuscating.
Counter-indication: classes that look for resource files in their package directories will no longer work properly if they are moved elsewhere. When in doubt, just leave the packaging untouched by not using this option.
-keeppackagenames
[package_filter]
Specifies not to obfuscate the given package names. The optional filter is a comma-separated list of package names. Package names can contain ?, *****, and ****** wildcards, and they can be preceded by the ! negator. Only applicable when obfuscating.
-keepattributes
[attribute_filter]
Specifies any optional attributes to be preserved. The attributes can be specified with one or more -keepattributes
directives. The optional filter is a comma-separated list of attribute names that Java virtual machines and ProGuard support. Attribute names can contain ?, *****, and ****** wildcards, and they can be preceded by the ! negator. For example, you should at least keep the Exceptions
, InnerClasses
, and Signature
attributes when processing a library. You should also keep the SourceFile
and LineNumberTable
attributes for producing useful obfuscated stack traces. Finally, you may want to keep annotations if your code depends on them. Only applicable when obfuscating.