Android : Proguard集成说明
Android : Explanation of Proguard Integration
我已经做了一些 Android 开发,我在我的一个项目中达到了一个地步,我想使用 Proguard 来缩小我的 APk 的大小并帮助dex 限制。不幸的是,我遇到了一些错误,堆栈溢出有答案,但它们似乎是针对那些更有经验的人。
我的问题是你的proguard-android.txt
和proguard-rules.pro
有什么关系?为什么有两个单独的文件,为什么它们采用不同的格式?这些文件中的语句何时调用,调用顺序如何?我只是在寻找在开发环境中使用 Progurad 的整体上下文的解释。
提前致谢。
ProGuard 操纵 Java 字节码的方式与您通过配置文件及其包含的规则告诉它的方式相同。 ProGuard 可以做很多事情。它可以完全破坏您的应用程序,因此您必须确保添加正确的规则。
我假设您为您的应用程序使用基于 Gradle 的构建。那么您可能遇到过为您的应用程序(或 Android 库)的发布版本启用 ProGuard 的代码片段:
android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile(‘proguard-android.txt'),
'proguard-rules.pro'
}
}
...
}
在配置中,列表 proguardFiles
告诉构建它必须使用哪些包含 ProGuard 规则的文件。此列表可以包含任意数量的文件。
为什么文件(proguard-android.txt
和 proguard-rules.pro
)定义不同?
神奇的getDefaultProguardFile(‘proguard-android.txt')
从Android SDK中的标准位置(位置是${ANDROID_SDK}/tools/proguard/
)加载名为proguard-android.txt
的文件。
其他配置文件在本地解析,因此文件 proguard-rules.pro
应位于当前 Gradle 模块的根目录中。
为什么会有两个单独的文件?还有proguard-android.txt
和proguard-rules.pro
有什么关系?
ProGuard 配置是附加的。您可以在一个文件中定义一些规则,而在其他文件中定义其他规则。这些规则在内部连接成单个规则列表。
文件 getDefaultProguardFile(‘proguard-android.txt')
包含所有 Android 应用程序的几个通用规则(在您的 SDK 中的文件中自行检查)。本地 proguard-rules.pro
应包含特定于您自己的应用程序的规则。例如,当您仅通过反射使用 class 时,您希望确保它不会被剥离(我稍后会谈到)。
请注意,拥有多个本地文件非常有用。例如,您可以使用两个本地配置文件进行调试构建 - 一个包含应用程序的发布规则,第二个包含禁用混淆的规则。
另请注意,配置的附加行为可能有点麻烦。如果您在一个配置文件中添加规则,则无法在另一个配置文件中删除它。所以要小心非常通用的规则(例如想象添加 -keep class ** { *; }
)。
何时调用这些文件中的语句,调用顺序是什么?
您可以按任何顺序定义它们,没有区别。而且你可以在多个文件中定义相同的规则,这没有关系。指定文件的顺序也无关紧要。
ProGuard 本身是 运行 作为 Android 构建中的单个作业(准确地说是单个 Gradle 任务)。该任务提供了所有输入:
- classes 操纵
- 库class可以使用但不能操作
- 生成的已处理 jar 的输出路径
- ProGuard 规则指定操作
- 各种输出信息的输出路径(删除的内容、映射等)
然后它处理文件并生成一个输出,该输出由 Gradle 构建进一步处理。
ProGuard 实际上是如何工作的?为什么我需要规则?
ProGuard遍历了classes/methods/fields/…的整个调用图。它以提供的规则定义的 classes/methods/… 开头。然后遍历调用图并根据需要标记 classes/methods/fields/... 并保留它们以供输出。因此,如果您在没有匹配保留规则的情况下调用它,它将生成一个空输出(或者它可能会抛出一个错误并告诉您定义一些,我现在不记得了)。 ProGuard 不识别通过反射完成的调用,因此您必须添加一些规则来处理它。还有许多其他情况需要您添加一些规则,请查看 documentation。
最后的笔记
如果你检查 ProGuard documentation 你可以找到各种规则
您可以使用。但并非所有规则都适用于 Android(ProGuard 是一种通用的 Java 工具)。
一些规则由Android 构建本身生成,您不必自己定义它们。此类规则有两种类型:
- 常规配置规则,例如
-injars
、-libraryjars
、...
- 从
AndroidManifest.xml
和资源(布局)生成的规则。 Android 构建(aapt 工具)生成规则以保留清单中提到的 classes(活动、服务、接收器,...)和布局中使用的自定义视图。您可以在 build/intermediates/proguard-rules/${PRODUCT_FLAVOR}/${BUILD_TYPE}/aapt_rules.txt
中查看这些生成的规则
一些规则可以来自 aar 库。这些库可以包含库工作所必需的 ProGuard 配置(内部可以有 proguard.txt
文件)。
当您自己编写 Android 库时,请特别注意要添加到 aar 中的规则。由于规则的附加性质,它可能会给捆绑库的应用程序带来问题。
我已经做了一些 Android 开发,我在我的一个项目中达到了一个地步,我想使用 Proguard 来缩小我的 APk 的大小并帮助dex 限制。不幸的是,我遇到了一些错误,堆栈溢出有答案,但它们似乎是针对那些更有经验的人。
我的问题是你的proguard-android.txt
和proguard-rules.pro
有什么关系?为什么有两个单独的文件,为什么它们采用不同的格式?这些文件中的语句何时调用,调用顺序如何?我只是在寻找在开发环境中使用 Progurad 的整体上下文的解释。
提前致谢。
ProGuard 操纵 Java 字节码的方式与您通过配置文件及其包含的规则告诉它的方式相同。 ProGuard 可以做很多事情。它可以完全破坏您的应用程序,因此您必须确保添加正确的规则。
我假设您为您的应用程序使用基于 Gradle 的构建。那么您可能遇到过为您的应用程序(或 Android 库)的发布版本启用 ProGuard 的代码片段:
android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile(‘proguard-android.txt'),
'proguard-rules.pro'
}
}
...
}
在配置中,列表 proguardFiles
告诉构建它必须使用哪些包含 ProGuard 规则的文件。此列表可以包含任意数量的文件。
为什么文件(proguard-android.txt
和 proguard-rules.pro
)定义不同?
神奇的getDefaultProguardFile(‘proguard-android.txt')
从Android SDK中的标准位置(位置是${ANDROID_SDK}/tools/proguard/
)加载名为proguard-android.txt
的文件。
其他配置文件在本地解析,因此文件 proguard-rules.pro
应位于当前 Gradle 模块的根目录中。
为什么会有两个单独的文件?还有proguard-android.txt
和proguard-rules.pro
有什么关系?
ProGuard 配置是附加的。您可以在一个文件中定义一些规则,而在其他文件中定义其他规则。这些规则在内部连接成单个规则列表。
文件 getDefaultProguardFile(‘proguard-android.txt')
包含所有 Android 应用程序的几个通用规则(在您的 SDK 中的文件中自行检查)。本地 proguard-rules.pro
应包含特定于您自己的应用程序的规则。例如,当您仅通过反射使用 class 时,您希望确保它不会被剥离(我稍后会谈到)。
请注意,拥有多个本地文件非常有用。例如,您可以使用两个本地配置文件进行调试构建 - 一个包含应用程序的发布规则,第二个包含禁用混淆的规则。
另请注意,配置的附加行为可能有点麻烦。如果您在一个配置文件中添加规则,则无法在另一个配置文件中删除它。所以要小心非常通用的规则(例如想象添加 -keep class ** { *; }
)。
何时调用这些文件中的语句,调用顺序是什么?
您可以按任何顺序定义它们,没有区别。而且你可以在多个文件中定义相同的规则,这没有关系。指定文件的顺序也无关紧要。
ProGuard 本身是 运行 作为 Android 构建中的单个作业(准确地说是单个 Gradle 任务)。该任务提供了所有输入:
- classes 操纵
- 库class可以使用但不能操作
- 生成的已处理 jar 的输出路径
- ProGuard 规则指定操作
- 各种输出信息的输出路径(删除的内容、映射等)
然后它处理文件并生成一个输出,该输出由 Gradle 构建进一步处理。
ProGuard 实际上是如何工作的?为什么我需要规则?
ProGuard遍历了classes/methods/fields/…的整个调用图。它以提供的规则定义的 classes/methods/… 开头。然后遍历调用图并根据需要标记 classes/methods/fields/... 并保留它们以供输出。因此,如果您在没有匹配保留规则的情况下调用它,它将生成一个空输出(或者它可能会抛出一个错误并告诉您定义一些,我现在不记得了)。 ProGuard 不识别通过反射完成的调用,因此您必须添加一些规则来处理它。还有许多其他情况需要您添加一些规则,请查看 documentation。
最后的笔记
如果你检查 ProGuard documentation 你可以找到各种规则 您可以使用。但并非所有规则都适用于 Android(ProGuard 是一种通用的 Java 工具)。
一些规则由Android 构建本身生成,您不必自己定义它们。此类规则有两种类型:
- 常规配置规则,例如
-injars
、-libraryjars
、... - 从
AndroidManifest.xml
和资源(布局)生成的规则。 Android 构建(aapt 工具)生成规则以保留清单中提到的 classes(活动、服务、接收器,...)和布局中使用的自定义视图。您可以在build/intermediates/proguard-rules/${PRODUCT_FLAVOR}/${BUILD_TYPE}/aapt_rules.txt
中查看这些生成的规则
一些规则可以来自 aar 库。这些库可以包含库工作所必需的 ProGuard 配置(内部可以有 proguard.txt
文件)。
当您自己编写 Android 库时,请特别注意要添加到 aar 中的规则。由于规则的附加性质,它可能会给捆绑库的应用程序带来问题。