Android 混淆打包之类名指定

本文详细介绍了Android ProGuard中关于类名混淆的指定规则,包括类的完全限定名、接口、枚举、通配符使用、字段和方法的指定方式,以及访问修饰符的限制。通过示例和正式的定义,帮助开发者更好地理解和应用ProGuard的类混淆策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



Class Specifications

A class specification is a template of classes and class members (fields and methods). It is used in the various  -keep  options and in the  -assumenosideeffects  option. The corresponding option is only applied to classes and class members that match the template.

The template was designed to look very Java-like, with some extensions for wildcards. To get a feel for the syntax, you should probably look at the examples, but this is an attempt at a complete formal definition:

[@annotationtype] [[!]public|final|abstract|@ ...] [!]interface|class|enum classname
    [extends|implements [@annotationtype] classname]
[{
    [@annotationtype] [[!]public|private|protected|static|volatile|transient ...] <fields> |
                                                                      (fieldtype fieldname);
    [@annotationtype] [[!]public|private|protected|static|synchronized|native|abstract|strictfp ...] <methods> |
                                                                                           <init>(argumenttype,...) |
                                                                                           classname(argumenttype,...) |
                                                                                           (returntype methodname(argumenttype,...));
    [@annotationtype] [[!]public|private|protected|static ... ] *;
    ...
}]

Square brackets "[]" mean that their contents are optional. Ellipsis dots "..." mean that any number of the preceding items may be specified. A vertical bar "|" delimits two alternatives. Non-bold parentheses "()" just group parts of the specification that belong together. The indentation tries to clarify the intended meaning, but white-space is irrelevant in actual configuration files.

  • The class keyword refers to any interface or class. The interface keyword restricts matches to interface classes. The enum keyword restricts matches to enumeration classes. Preceding the interface or enum keywords by a ! restricts matches to classes that are not interfaces or enumerations, respectively.
  • Every classname must be fully qualified, e.g. java.lang.String. Inner classes are separated by a dollar sign "$", e.g. java.lang.Thread$State. Class names may be specified as regular expressions containing the following wildcards:
    ?matches any single character in a class name, but not the package separator. For example, "mypackage.Test?" matches "mypackage.Test1" and "mypackage.Test2", but not "mypackage.Test12".
    *matches any part of a class name not containing the package separator. For example, "mypackage.*Test*" matches "mypackage.Test" and "mypackage.YourTestApplication", but not "mypackage.mysubpackage.MyTest". Or, more generally, "mypackage.*" matches all classes in "mypackage", but not in its subpackages.
    **matches any part of a class name, possibly containing any number of package separators. For example, "**.Test" matches all Testclasses in all packages except the root package. Or, "mypackage.**" matches all classes in "mypackage" and in its subpackages.
    For additional flexibility, class names can actually be comma-separated lists of class names, with optional ! negators, just like file name filters. This notation doesn't look very Java-like, so it should be used with moderation.

    For convenience and for backward compatibility, the class name * refers to any class, irrespective of its package.

  • The extends and implements specifications are typically used to restrict classes with wildcards. They are currently equivalent, specifying that only classes extending or implementing the given class qualify. Note that the given class itself is not included in this set. If required, it should be specified in a separate option.
  • The @ specifications can be used to restrict classes and class members to the ones that are annotated with the specified annotation types. An annotationtype is specified just like a classname.
  • Fields and methods are specified much like in Java, except that method argument lists don't contain argument names (just like in other tools like javadoc and javap). The specifications can also contain the following catch-all wildcards:
    <init>matches any constructor.
    <fields>matches any field.
    <methods>matches any method.
    *matches any field or method.
    Note that the above wildcards don't have return types. Only the <init> wildcard has an argument list.

    Fields and methods may also be specified using regular expressions. Names can contain the following wildcards:

    ?matches any single character in a method name.
    *matches any part of a method name.

    Types in descriptors can contain the following wildcards:

    %matches any primitive type ("boolean", "int", etc, but not "void").
    ?matches any single character in a class name.
    *matches any part of a class name not containing the package separator.
    **matches any part of a class name, possibly containing any number of package separators.
    ***matches any type (primitive or non-primitive, array or non-array).
    ...matches any number of arguments of any type.

    Note that the ?*, and ** wildcards will never match primitive types. Furthermore, only the *** wildcards will match array types of any dimension. For example, "** get*()" matches "java.lang.Object getObject()", but not "float getFloat()", nor "java.lang.Object[] getObjects()".

  • Constructors can also be specified using their short class names (without package) or using their full class names. As in the Java language, the constructor specification has an argument list, but no return type.
  • The class access modifiers and class member access modifiers are typically used to restrict wildcarded classes and class members. They specify that the corresponding access flags have to be set for the member to match. A preceding ! specifies that the corresponding access flag should be unset.

    Combining multiple flags is allowed (e.g. public static). It means that both access flags have to be set (e.g. public and static), except when they are conflicting, in which case at least one of them has to be set (e.g. at least public or protected).

    ProGuard supports the additional modifiers syntheticbridge, and varargs, which may be set by compilers.

通配符匹配规则

通配符 规则
匹配单个字符
* 匹配类名中的任何部分,但不包含额外的包名
** 匹配类名中的任何部分,并且可以包含额外的包名
% 匹配任何基础类型的类型名
* 匹配任意类型名 ,包含基础类型/非基础类型
... 匹配任意数量、任意类型的参数
<init> 匹配任何构造器
<ifield> 匹配任何字段名
<imethod> 匹配任何方法
*(当用在类内部时) 匹配任何字段和方法
$ 指内部类

更详细的语法请戳:http://proguard.sourceforge.net/manual/usage.html#classspecification


Android Studio中进行打包混淆时,可能会遇到包冲突的报错。这种情况下,需要解决包冲突问题。 首先,查看报错信息中提到的包冲突详情。在你提供的引用中,报错信息中提到了冲突的包路径为"android/support/design/widget/CoordinatorLayout$LayoutParams.class"。 解决包冲突的方法有多种,以下是一种解决方法: 1. 打开项目中的build.gradle文件。 2. 在buildTypes中找到release配置,并将minifyEnabled属性设置为true,表示开启代码混淆。 3. 在proguardFiles中添加proguard-rules.pro文件,该文件用于指定混淆规则。 4. 在proguard-rules.pro文件中添加以下规则,以保持特定的类和接口不被混淆: -keep class okhttp3.** { *; } -keep interface okhttp3.** { *; } -dontwarn okhttp3.** -keep class okio.** { *; } -keep interface okio.** { *; } -dontwarn okio.** -keep class com.hitomi.** { *; } -keep interface com.hitomi.** { *; } -dontwarn com.hitomi.** 5. 重新编译并打包你的应用程序,这次应该不再出现包冲突的报错。 请注意,这只是一种解决包冲突问题的方法之一。在实际操作中,可能需要根据具体情况进行调整和修改。 参考引用: - http://blog.youkuaiyun.com/u012246458/article/details/79446784 - build.gradle文件中的代码 - proguard-rules.pro文件中的代码<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [AndroidStudio打包混淆](https://blog.youkuaiyun.com/qq_24570087/article/details/80620546)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值