AAPT2
AAPT2(Android资源打包工具)是一种构建工具,Android Studio 和 Android Gradle 插件使用它来编译和打包应用的资源。AAPT2 会解析资源、为资源编制索引,并将资源编译为针对 Android 平台进行过优化的二进制格式。
可以在 android_sdk/build-tools/version/ 下找到 AAPT2,AAPT2 支持通过启用增量编译实现更快的资源编译。这是通过将资源处理拆分为两个步骤来实现的:
- 编译:将资源文件编译为二进制格式。
- 链接:合并所有已编译的文件并将它们打包到一个软件包中。
这种拆分方式有助于提高增量编译的性能。例如,如果某个文件中有更改,您只需要重新编译该文件。
编译
AAPT2 支持编译所有 Android 资源类型,如可绘制对象和 XML 文件。调用 AAPT2 进行编译时,每次调用都应传递一个资源文件作为输入。然后,AAPT2 会解析该文件并生成一个扩展名为 .flat 的中间二进制文件。
输出文件的类型可能会因您为编译提供的输入而异。下表对此进行了说明:
输入 | 输出 |
---|
XML 资源文件(如 String 和 Style),它们位于 res/values/ 目录下。 | 以 *.arsc.flat 作为扩展名的资源表。 | 其他所有资源文件。 | 除 res/values/ 目录下的文件以外的其他所有文件都将转换为扩展名为 *.flat 的二进制 XML 文件。此外,默认情况下,所有 PNG 文件都会被压缩,并采用 *.png.flat 扩展名。如果选择不压缩 PNG,您可以在编译期间使用 --no-crunch 选项。 |
AAPT2 输出的文件不是可执行文件,稍后必须在链接阶段添加这些二进制文件作为输入来生成 APK。但是,所生成的 APK 文件不是可以立即部署在 Android 设备上的可执行文件,因为它不包含 DEX 文件(已编译的字节码)且未签名。
编译语法
使用 compile 的一般语法如下:
aapt2 compile path-to-input-files [options] -o output-directory/
注意:对于资源文件,输入文件的路径必须符合以下结构: path/resource-type[-config]/file
在以下示例中,AAPT2 分别编译了名为 values.xml 和 myImage.png 的资源文件:
aapt2 compile project_root/module_root/src/main/res/values-en/strings.xml -o compiled/
aapt2 compile project_root/module_root/src/main/res/drawable /myImage.png -o compiled/
aapt2 compile C:\Users\Administrator\Desktop\res\values\strings.xml -v -o C:\Users\Administrator\Desktop\compile
如上表中所示,输出文件的名称取决于输入文件的名称及其父目录(资源类型和配置)的名称。对于以 strings.xml 作为输入的上述示例,aapt2 会自动将输出文件命名为 values-en_strings.arsc.flat 。另一方面,存储在 drawable 目录中的已编译可绘制对象文件的文件名将为 drawable_img.png.flat 。
编译后的结果如下图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f0Y0pW93-1635469665559)(D:\gitbook_note\Android\command\QQ截图20210331141013.png)]
编译选项
可以将多个选项与 compile 命令搭配使用,如下表中所示:
选项 | 说明 |
---|
-o path | 指定已编译资源的输出路径。这是一个必需的标记,因为您必须指定 AAPT2 可将已编译的资源输出并存储到其中的目录的路径。这个参数可以是目录,也可以是文件,取决于输入的资源文件是目录还是文件。假如输入的是目录,则输出的是个zip压缩包,参数值必须是个文件(要添加–dir 参数);输入的是单个资源文件,则输出的是一个flat文件,参数值必须是个目录,输出的文件名由aapt2生成。 | --dir directory | 指定要在其中搜索资源的目录。虽然您可以使用此标记通过一个命令编译多个资源文件,但这样就无法获得增量编译的优势,因此不建议对大型项目使用。 | --pseudo-localize | 生成默认字符串的伪本地化版本,如 en-XA 和 en-XB。 | --no-crunch | 停用 PNG 处理。如果您已处理 PNG 文件,或者要创建不需要减小文件大小的调试 build,则可使用此选项。启用此选项可以加快执行速度,但会增大输出文件大小。 | --legacy | 将使用早期版本的 AAPT 时允许的错误视为警告。此标记应用于意外的编译时错误。 | -v | 启用详细日志记录。 |
链接
在链接阶段,AAPT2 会合并在编译阶段生成的所有中间文件(如资源表、二进制 XML 文件和处理过的 PNG 文件),并将它们打包成一个 APK。此外,在此阶段还会生成其他辅助文件,如 R.java 和 ProGuard 规则文件。不过,生成的 APK 不包含 DEX 字节码且未签名。也就是说,您无法将此 APK 部署到设备。如果您不使用 Android Gradle 插件从命令行构建应用,则可以使用其他命令行工具,如使用 d8 将 Java 字节码编译为 DEX 字节码,以及使用 apksigner 为 APK 签名。
链接语法
aapt2 link path-to-input-files [options] -o outputdirectory/outputfilename.apk --manifest AndroidManifest.xml
aapt2 link compile\res.zip compile\res1\drawable_check_box_selector.xml.flat -I D:\software\sdk\platforms\android-29\android.jar --java compile\package -o compile\output.apk --manifest D:\AndroidStudioProjects\FYSDK3.1\sdktest\src\main\AndroidManifest.xml -v
在以下示例中,AAPT2 将两个中间文件(drawable_Image.flat 和 values_values.arsc.flat )与 AndroidManifest.xml 文件进行了合并。AAPT2 会根据 android.jar 文件链接结果,该文件中包含了 Android 软件包中定义的资源:
aapt2 link -o output.apk -I android_sdk/platforms/android_version/android.jar compiled/res/values_values.arsc.flat compiled/res/drawable_Image.flat --manifest /path/to/AndroidManifest.xml -v
aapt2 link compile\res.zip compile\res1\drawable_check_box_selector.xml.flat -I D:\software\sdk\platforms\android-29\android.jar --java compile\package -o compile\output.apk --manifest D:\AndroidStudioProjects\FYSDK3.1\sdktest\src\main\AndroidManifest.xml -v
链接选项
您可以将以下选项与 link 命令搭配使用:
选项 | 说明 |
---|
-o path | 指定链接的资源 APK 的输出路径。这是一个必需的标记,因为您必须指定可以存放链接资源的输出 APK 的路径。 | --manifest file | 指定要构建的 Android 清单文件的路径。这是一个必需的标记,因为清单文件中包含有关您应用的基本信息(如软件包名称和应用 ID)。file就是应用中AndroidMainest.xml的路径。 | -I | 提供平台的 android.jar 或其他 APK(如 framework-res.apk )的路径,这在构建功能时可能很有用。如果您要在资源文件中使用带有 android 命名空间(例如 android:id )的属性,则必须使用此标记。 | -A directory | 指定要包含在 APK 中的资产目录。您可以使用此目录存储未处理的原始文件。 | -R file | 传递要链接的单个 .flat 文件,使用 overlay 语义,而不使用 <add-resource> 标记。如果您提供与现有文件重叠(扩展或修改现有文件)的资源文件,系统会使用最后提供的冲突资源。 | --package-id package-id | 指定要用于应用的软件包 ID。除非与 --allow-reserved-package-id 结合使用,否则您指定的软件包 ID 必须大于或等于 0x7f。 | --allow-reserved-package-id | 允许使用保留的软件包 ID。保留的软件包 ID 是指通常分配给共享库的 ID,范围从 0x02 到 0x7e(包含端点值)。通过使用 --allow-reserved-package-id ,您可以分配属于保留的软件包 ID 范围内的 ID。此选项只能用于最低 SDK 版本为 26 或更低版本的软件包。 | --java directory | 指定要在其中生成 R.java 的目录。 | --proguard proguard_options | 为 ProGuard 规则生成输出文件。 | --proguard-conditional-keep-rules | 为主 dex 的 ProGuard 规则生成输出文件。 | --no-auto-version | 停用自动样式和布局 SDK 版本控制。 | --no-version-vectors | 停用矢量可绘制对象的自动版本控制。 仅当使用矢量可绘制对象库构建 APK 时,才能使用此选项。 | --no-version-transitions | 停用转换资源的自动版本控制。 仅当使用转换支持库构建 APK 时,才能使用此选项。 | --no-resource-deduping | 禁止在兼容配置中自动删除具有相同值的重复资源。 | --enable-sparse-encoding | 允许使用二进制搜索树对稀疏条目进行编码。 这有助于优化 APK 大小,但会降低资源检索性能。 | -z | 要求对标记为“建议”的字符串进行本地化。 | -c config | 提供以英文逗号分隔的配置列表。例如,如果您依赖于支持库(该支持库包含多种语言的翻译),则可以仅针对给定的语言配置(如英语或西班牙语)过滤资源。您必须使用两个字母的 ISO 639-1 语言代码定义语言配置,后面可选择性地添加两个字母的 ISO 3166-1-alpha-2 区域代码(在区域代码前加上小写的“r”,例如 en-rUS)。 | --preferred-density density | 允许 AAPT2 选择最相符的密度并移除其他所有密度。您可以在应用中使用多种像素密度限定符,如 ldpi、hdpi 和 xhdpi。在您指定首选密度后,AAPT2 会选择最相符的密度并将其存储在资源表中,然后移除其他所有密度。 | --output-to-dir | 将 APK 内容输出到 -o 指定的目录中。如果您在使用此标记时遇到任何错误,可以通过升级到 Android SDK Build Tools 28.0.0 或更高版本来解决这些问题。 | --min-sdk-version min-sdk-version | 设置要用于 AndroidManifest.xml 的默认最低 SDK 版本。 | --target-sdk-version target-sdk-version | 设置要用于 AndroidManifest.xml 的默认目标 SDK 版本。 | --version-code version-code | 指定没有版本代码时要注入 AndroidManifest.xml 中的版本代码(整数)。 | --compile-sdk-version-name compile-sdk-version-name | 指定没有版本名称时要注入 AndroidManifest.xml 中的版本名称。 | --proto-format | 以 Protobuf 格式生成已编译的资源。适合作为 bundle tool 的输入,用于生成 Android App Bundle。 | --non-final-ids | 使用非最终资源 ID 生成 R.java (在 kotlinc/javac 编译期间,系统不会内嵌从应用的代码对这些 ID 的引用)。 | --emit-ids path | 在给定的路径下生成一个文件,该文件包含资源类型的名称及其 ID 映射的列表。它适合与 --stable-ids 搭配使用。 | --stable-ids outputfilename.ext | 使用通过 --emit-ids 生成的文件,该文件包含资源类型的名称以及为其分配的 ID 的列表。此选项可以让已分配的 ID 保持稳定,即使您在链接时删除了资源或添加了新资源也是如此。 | --custom-package package_name | 指定要在其下生成 R.java 的自定义 Java 软件包。 | --extra-packages package_name | 生成相同的 R.java 文件,但软件包名称不同。 | --add-javadoc-annotation annotation | 向已生成的所有 Java 类添加 JavaDoc 注释。 | --output-text-symbols path | 生成包含指定文件中 R 类的资源符号的文本文件。您必须指定输出文件的路径。 | --auto-add-overlay | 允许在叠加层中添加新资源,而不使用 <add-resource> 标记。 | --rename-manifest-package manifest-package | 重命名 AndroidManifest.xml 中的软件包。 | --rename-instrumentation-target-package instrumentation- target-package | 更改插桩的目标软件包的名称。它应与 --rename-manifest-package 结合使用。 | -0 extension | 指定您不想压缩的文件的扩展名。 | --split path:config[,config[..]] | 根据一组配置拆分资源,以生成另一个版本的 APK。您必须指定输出 APK 的路径和一组配置。 | -v | 可提高输出的详细程度。 |
转储
dump (转储) 用于输出有关您使用 link 命令生成的 APK 的信息。例如,以下命令的输出结果为所指定 APK 的资源表中的内容:
aapt2 dump resources output.apk
转储语法
aapt2 dump sub-command(子命令) filename.apk [options]
转储子命令
子命令 | 说明 |
---|
apc | 输出在编译期间生成的 AAPT2 容器(APC)的内容。 | badging | 输出从 APK 的清单中提取的信息。 | configurations | 输出 APK 中的资源使用的每项配置。 | packagename | 输出 APK 的软件包名称。 | permissions | 输出从 APK 的清单提取的权限。 | strings | 输出 APK 的资源表字符串池的内容。 | styleparents | 输出 APK 中使用的样式的父项。 | resources | 输出 APK 的资源表的内容。 | xmlstrings | 输出 APK 的已编译 xml 中的字符串。 | xmltree | 输出 APK 的已编译 xml 树。 |
转储选项
可以将以下选项与 dump 搭配使用:
选项 | 说明 |
---|
--no-values | 禁止在显示资源时输出值。 | --file file | 将文件指定为要从 APK 转储的参数。 | -v | 提高输出的详细程度。 |
参考文档:
Google官方文档
APK编译流程-详解AAPT
|