我做Android开发已经有一段时间了,在我的一个项目中,我想使用Proguard来缩小我的APk的大小,并帮助解决索引限制。不幸的是,我得到了一些错误和堆栈溢出的答案,但他们似乎是针对那些有更多经验。
我的问题是你的proguard-android.txt
和proguard-rules.pro
是什么关系?为什么有两个单独的文件,为什么它们采用不同的格式?这些文件中的语句何时调用,以什么顺序调用?我只是在寻找在开发环境中使用Progurad的总体背景的解释。
提前感谢。
ProGuard操作Java字节码的方式与您的配置文件及其包含的规则相同。ProGuard可以做很多事情。它可能会彻底破坏你的应用,所以你必须确保添加正确的规则。
我假设你使用Gradle为你的应用构建。然后你可能遇到过这样的代码片段,它使ProGuard能够发布你的应用程序(或Android库):
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
预计包含特定于你自己的应用程序的规则。例如,你想确保一个类在你只通过反射使用它时不会被剥离(我将在稍后讨论)。
注意,拥有多个本地文件是非常有用的。例如,你可以使用两个本地配置文件进行调试构建——一个包含应用程序的发布规则,另一个包含禁用混淆的规则。
还要注意,配置的附加行为可能有点麻烦。如果在一个配置文件中添加了规则,则不能在另一个配置文件中删除它。所以要小心非常一般的规则(例如,想象添加-keep class ** { *; }
)。
这些文件中的语句何时调用,以什么顺序调用?
你可以用任何顺序定义它们,没有区别。您可以在多个文件中定义相同的规则,这无关紧要。指定文件的顺序也不重要。
ProGuard本身是作为Android构建中的单个任务运行的(确切地说是单个Gradle任务)。该任务提供了所有输入:
- 类来操作
- 使用但不能操作的库类
- 生成的已处理jar的输出路径
- ProGuard规则指定操作
- 各种输出信息的输出路径(删除的内容,映射,…)
然后它处理文件并生成一个输出,该输出由Gradle构建进一步处理。
ProGuard实际上是如何工作的?我为什么需要这些规则?
ProGuard遍历类/方法/字段/....的整个调用图它从所提供的规则定义的类/方法/…开始。然后遍历调用图并根据需要标记类/方法/字段/…,并将它们保留为输出。因此,如果您在没有匹配keep规则的情况下调用它,它将生成一个空输出(或者它可能会抛出一个错误,并告诉您定义一些,我现在不记得了)。ProGuard不识别通过反射完成的调用,所以你必须添加一些规则来处理这个问题。还有许多其他情况需要您添加一些规则,请查看文档。
最后指出
如果你检查ProGuard文档,你可以找到各种规则你可以用。但并不是所有的规则都适用于Android (ProGuard是一个通用的Java工具)。
一些规则是由Android自身生成的,你不必自己定义它们。这样的规则有两种类型:
-
-injars
,-libraryjars
,…等通用配置规则 - 由
AndroidManifest.xml
和资源(布局)生成的规则。Android build (aapt工具)生成规则来保留清单中提到的类(activity, services, receiver,…)和在布局中使用的自定义视图。您可以在build/intermediates/proguard-rules/${PRODUCT_FLAVOR}/${BUILD_TYPE}/aapt_rules.txt
中检查这些生成的规则。
一些规则可以来自和库。库可以包含库工作所需的ProGuard配置(里面可以有proguard.txt
文件)。
当你自己编写Android库时,要非常小心你想要添加到aar中的规则。由于规则的附加性,它可能会给绑定库的应用带来问题。