AAPT2(Android 资源打包工具)是一种构建工具,Android Studio 和 Android Gradle 插件使用它来编译和打包应用的资源。AAPT2 会解析资源、为资源编制索引,并将资源编译为针对 Android 平台进行过优化的二进制格式。
Android Gradle 插件 3.0.0 及更高版本在默认情况下会启用 AAPT2。您通常不需要自行调用 aapt2
。不过,如果您更愿意使用自己的终端和构��系统而不是 Android Studio,则可以从命令行使用 AAPT2。您还可以从命令行调试与 AAPT2 相关的构建错误。为此,您可以在 Android SDK Build Tools 26.0.2 及更高版本中找到作为独立工具提供的 AAPT2。
如要从命令行下载 Android SDK Build Tools,请使用 sdkmanager
并运行以下命令:
sdkmanager "build-tools;build-tools-version"
下载 SDK Build Tools 后,在 android_sdk/build-tools/version/
下找到 AAPT2。
由于 Android SDK Build Tools 不常发布新版本,因此 SDK Build Tools 中包含的 AAPT2 可能不是最新版本。如需获取最新版 AAPT2,请参阅从 Google Maven 下载 AAPT2。
如需在 Linux 或 Mac 上从命令行使用 AAPT2,请运行 aapt2
命令。在 Windows 上,运行 aapt2.exe
命令。
AAPT2 支持通过启用增量编译实现更快的资源编译。为实现增量编译,资源处理被拆分为两个步骤:
这种拆分方式有助于提高增量编译的性能。例如,如果某个文件中有更改,您只需要重新编译该文件。
从 Google Maven 下载 AAPT2
如需获得未捆绑在构建工具中的最新版 AAPT2,您可以从 Google 的 Maven 制品库下载 AAPT2,具体操作步骤如下:
- 在制品库索引中,依次前往 com.android.tools.build > aapt2。
- 复制最新版 AAPT2 的名称。
将复制的版本名称插入以下网址并指定目标操作系统: https://dl.google.com/dl/android/maven2/com/android/tools/build/aapt2/ aapt2-version/aapt2-aapt2-version- [windows | linux | osx].jar
例如,如需下载适用于 Windows 的版本 3.2.0-alpha18-4804415,请使用: https://dl.google.com/dl/android/maven2/com/android/tools/build/aapt2/ 3.2.0-alpha18-4804415/aapt2-3.2.0-alpha18-4804415-windows.jar
在浏览器中前往该网址,系统将随即开始下载 AAPT2。
解压缩刚刚下载的 JAR 文件。
JAR 文件应包含
aapt2
可执行文件和该可执行文件所依赖的一些库。
编译
AAPT2 支持编译所有 Android 资源类型,如可绘制对象和 XML 文件。调用 AAPT2 进行编译时,每次调用都会传递一个资源文件���为输入。然后,AAPT2 会解析该文件并生成一个扩展名为 .flat
的中间二进制文件。
如果传递整个目录,则即使只有一项资源发生了改变,AAPT2 也会重新编译目录中的所有文件。虽然您可以使用 --dir
标记将包含多个资源文件的资源目录传递给 AAPT2,但如果这样做,您将无法获得增量资源编译的优势。
输出文件的类型可能会因您为编译提供的输入而异,如下表所示:
表 1. 编译的输入和输出文件类型
输入 | 输出 |
---|---|
XML 资源文件(如 String 和 Style),均位于 res/values/ 目录下。
|
以 *.arsc.flat 作为扩展名的资源表。
|
其他所有资源文件。 |
除
此外,默认情况下,所有 PNG 文件都会被压缩,并采用 |
AAPT2 输出的文件不是可执行文件,稍后您必须在链接阶段添加这些二进制文件作为输入来生成 APK。但是,所生成的 APK 文件不是可以立即部署在 Android 设备上的可执行文件,因为它不包含 DEX 文件且未签名。
编译语法
使用 compile
的一般语法如下:
aapt2 compile path-to-input-files [options] -o output-directory/
在以下示例中,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/
如表 1 中所示,输出文件的名称取决于输入文件的名称及其父级目录的名称。
对于以 strings.xml
文件作为输入的上述示例,aapt2
会自动将输出文件命名为 values-en_strings.arsc.flat
。不过,存储在 drawable 目录中的已编译可绘制对象文件的文件名将为 drawable_img.png.flat
。
编译选项
您可以将多个选项与 compile
命令搭��使用,如表 2 中所示:
表 2. 编译命令选项
选项 | 说明 |
---|---|
-o path
|
指定已编译资源的输出路径。 这是一个必需的标记,因为您必须指定 AAPT2 可将已编译的资源输出并存储到其中的目录的路径。 |
--dir directory
|
指定要在其中搜索资源的目录。 虽然您可以使用此标记通过一个命令编译多个资源文件,但这样就无法获得增量编译的优势。因此,此标记不应被用于大型项目。 |
--pseudo-localize
|
生成默认字符串的伪本地化版本,如 en-XA 和 en-XB 。
|
--no-crunch
|
停用 PNG 处理。
如果您已处理 PNG 文件,或者要创建不需要减小文件大小的调试 build,则可使用此选项。启用此选项可以加快执行速度,但会增大输出文件大小。 |
--legacy
|
将使用早期版本的 AAPT 时允许的错误视为警告。
此标记应用于意外的编译时错误。如需解决在使用 AAPT2 时可能发生的已知行为变化,请参阅 AAPT2 中的行为变化。 |
-zip file
|
file 是一个 ZIP 文件,包含要在其中搜索资源的 res 目录。
|
-output-text-symbols file
|
生成包含指定 |
-preserve-visibility-of-styleables
|
如果已指定,则将对所有其他资源使用的可设置样式项应用相同的可见性规则。如果未指定,所有可设置样式项都将公开。 |
-visibility [public|private|default|]
|
将已编译资源的可见性设置为指定级别。 |
-trace-folder folder
|
生成一个 systrace JSON 跟踪记录 fragment,其保存在指定 |
-source-path path
|
将已编译资源文件的源文件路径设置为 |
-h
|
显示工具帮助。 |
-v
|
启用详细日志记录。 |
链接
在链接阶段,AAPT2 会合并在编译阶段生成的所有中间文件(如资源表、二进制 XML 文件和处理过的 PNG 文件),并将它们打包成一个 APK。此外,在此阶段还会生成其他辅助文件,如 R.java
和 ProGuard 规则文件。不过,生成的 APK 不包含 DEX 字节码且未签名。您无法将此 APK 部署到设备。
如果您不使用 Android Gradle 插件从命令行构建应用,则可以使用其他命令行工具,如使用 d8 将 Java 字节码编译为 DEX 字节码,以及使用 apksigner 为 APK 签名。
链接语法
使用 link
的一般语法如下:
aapt2 link path-to-input-files [options] -o outputdirectory/outputfilename.apk --manifest AndroidManifest.xml
在以下示例中,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
链接选项
您可以将以下选项与 link
命令搭配使用:
表 3. 链接命令选项
选项 | 说明 |
---|---|
-o path
|
指定链接的资源 APK 的输出路径。 这是一个必需的标记,因为您必须指定可以存放链接资源的输出 APK 的路径。 |
--manifest file
|
指定要构建的 Android 清单文件的路径。 这是一个必需的标记,因为清单文件中包含有关您应用的基本信息(如软件包名称和应用 ID)。 |
-I
|
提供平台的 android 命名空间的属性,则必须使用此标记。
|
-A directory
|
指定要包含在 APK 中的资源目录。
您可以使用此目录存储未处理的原始文件。如需了解详情,请参阅访问原始文件。 |
-R file
|
将单个 .flat 文件传递到 link ,使用 overlay 语义,而不使用 <add-resource> 标记。
如果您提供与现有文件叠加的资源文件,系统会使用最后提供的冲突资源。 |
--package-id package-id
|
指定要用于应用的软件包 ID。
除非与 |
--allow-reserved-package-id
|
允许使用保留的软件包 ID。 保留的软件包 ID 是指通常分配给共享库的 ID,范围从 0x02 到 0x7e(包含端点值)。通过使用 此选项只能用于 |
--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 中的版本代码。
|
--version-name version-name
|
指定没有版本名称时要注入 AndroidManifest.xml 中的版本名称。
|
--revision-code revision-code
|
指定没有修订代码时要注入 AndroidManifest.xml 文件中的修订代码。
|
--replace-version
|
如果指定了 --version-code 、--version-name 或 --revision-code ,这些值将替换清单中已有的任何值。默认情况下,如果清单已经定义这些属性,则不会有任何变化。
|
--compile-sdk-version-nacodeme compile-sdk-version-name
|
指定没有版本代码时要注入 AndroidManifest.xml 文件中的版本代码。
|
--compile-sdk-version-name compile-sdk-version-name
|
指定没有版本名称时要注入 AndroidManifest.xml 文件中的版本名称。
|
--proto-format
|
以 Protobuf 格式生成已编译的资源。
适合作为 |
--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
|
更改 instrumentation 的目标软件包的名称。
此选项应与 |
-0 extension
|
指定您不想压缩的文件的扩展名。 |
--split path:config[,config[..]]
|
根据一组配置拆分资源,以生成另一个版本的 APK。
您必须指定输出 APK 的路径和一组配置。 |
--proguard-main-dex file
|
为主 DEX 生成的 ProGuard 规则的输出文件。 |
--proguard-minimal-keep-rules
|
生成一组最小限度的 ProGuard 保留规则。 |
--no-resource-removal
|
停用资源自动移除功能(在没有默认值的情况下)。仅在构建运行时资源叠加层软件包时使用此选项。 |
-x
|
用于指定使用软件包标识符 0x01 的旧版标记。 |
--product products-list
|
以逗号分隔列表的形式指定要保留的产品名称。 |
--no-xml-namespaces
|
从 AndroidManifest.xml 文件和 res/* 中 XML 二进制文件中移除 XML 命名空间前缀和 URI 信息。
|
--shared-lib
|
生成共享的 Android 运行时库。 |
--static-lib
|
生成静态的 Android 库。 |
--no-static-lib-packages
|
合并应用软件包下的所有库资源。 |
--no-proguard-location-reference
|
阻止 ProGuard 规则文件引用源文件。 |
--private-symbols package-name
|
package-name 指定在为私有符号生成 R.java 时要使用的软件包名称。如果未指定,则公共和私有符号都将使用应用的软件包名称。
|
--override-styles-instead-of-overlaying
|
使 -R 资源中定义的样式取代之前的定义,而非合并这些定义。
|
--rename-resources-package package-name
|
将资源表中的软件包重命名为 package-name。 |
--no-compress
|
不压缩任何资源。 |
--keep-raw-values
|
保留 XML 文件中的原始属性值。 |
--no-compress-regex regular-expression
|
不压缩与 regular-expression 匹配的扩展程序。
使用 $ 符号表示行尾。使用区分大小写的 ECMAScript 正则表达式语法。
|
--warn-manifest-validation
|
将清单验证错误视为警告。 |
--exclude-configs qualifier[,qualifier[..]]
|
排除配置包含指定限定符的资源的值。 |
--debug-mode
|
将 android:debuggable="true" 插入清单的应用节点,使应用即使在正式版设备上也可调试。
|
--strict-visibility
|
不允许显示可见性级别不同的叠加层。 |
--exclude-sources
|
以 Protobuf 格式生成资源时,不会将源文件信息序列化。 |
--trace-folder folder
|
生成 systrace JSON 跟踪记录 fragment,其保存在指定的folder中。
|
--merge-only
|
仅在不验证资源引用的情况下合并资源。此标志应仅与 --static-lib 标志一起使用。
|
-h
|
显示帮助菜单。 |
-v
|
可提高输出的详细程度。 |
转储
dump
用于输出有关您使用 link
命令生成的 APK 的信息。
转储语法
使用 dump
的一般语法如下:
aapt2 dump sub-command filename.apk [options]
以下示例会输出所指定 APK 的资源表中的内容:
aapt2 dump resources output.apk
转储子命令
使用 dump
命令指定以下子命令之一:
表 4. 转储子命令
子命令 | 说明 |
---|---|
apc
|
输出在编译期间生成的 AAPT2 容器(APC)的内容。 |
badging
|
输出从 APK 的清单中提取的信息。 |
configurations
|
输出 APK 中的资源使用的每项配置。 |
overlayable
|
输出 APK 的可叠加资源。 |
packagename
|
输出 APK 的软件包名称。 |
permissions
|
输出从 APK 的清单提取的权限。 |
strings
|
输出 APK 的资源表字符串池的内容。 |
styleparents
|
输出 APK 中使用的样式的父项。 |
resources
|
输出 APK 的资源表的内容。 |
xmlstrings
|
输出 APK 的已编译 XML 中的字符串。 |
xmltree
|
输出 APK 的已编译 XML 树。 |
转储选项
将以下选项与 dump
搭配使用:
表 5. 转储选项
选项 | 说明 |
---|---|
--no-values
|
禁止在显示资源时输出值。 |
--file file
|
将文件指定为要从 APK 转储的参数。 |
-v
|
提高输出的详细程度。 |
diff
使用 diff
比较两个 APK 并确定它们之间的任何差异。
差异比较语法
使用 diff
的一般语法如下:
aapt2 diff first.apk second.apk
没有适用于 diff
命令的选项。
优化
optimize
用于在合并后的资源和 resources.arsc
被打包到 APK 之前对其运行优化。这项优化可将 APK 大小缩减约 1-3%,具体取决于所用资源的大小和数量。
优化语法
使用 optimize
的一般语法如下:
aapt2 optimize options file[,file[..]]
以下示例会优化 input.apk
中的资源,并在 output.apk
中创建一个经过优化的新 APK。它使用更紧凑的二进制搜索树替换通常的平面表格表示法,可以让 APK 体量更小,但检索性能会下降:
aapt2 optimize -o output.apk --enable-sparse-encoding input.apk
优化选项
您可以将以下选项与 optimize
搭配使用:
表 6. 优化选项
选项 | 说明 |
---|---|
-o path
|
指定链接的资源 APK 的输出路径。
这是一个必需的标记,因为您必须指定可以存放链接资源的输出 APK 的路径。 |
-d directory
|
指定拆分的输出目录的路径。 |
-x path
|
指定 XML 配置文件的路径。 |
-p
|
输出多 APK 工件及退出。 |
--target-densities density[,density[..]]
|
以逗号分隔列表的形式指定优化 APK 所针对的屏幕密度。系统会从 APK 中移除在给定密度的设备上未使用的所有资源。 |
--resources-config-path path
|
指定 格式:type/resource_name#[directive][,directive] |
-c config[,config[..]]
|
以逗号分隔列表的形式指定要包含的配置。默认值为所有配置。 |
--split path:config[,config[..]]
|
根据一组配置拆分资源,以生成另一个版本的 APK。
您必须指定输出 APK 的路径和一组配置。 |
--keep-artifacts artifact[,artifact[..]]
|
以逗号分隔列表的形式指定要保留的工件。如果未指定任何工件,系统会保留所有工件。 |
--enable-sparse-encoding
|
允许使用二进制搜索树对稀疏条目进行编码。 此选项有助于优化 APK 大小,但会降低资源检索性能。 |
--collapse-resource-names
|
将资源名称收起,仅显示键字符串池中的单个值。
在 --resources-config-path 指定的文件中,no_collapse 指令可豁免资源。
|
--shorten-resource-paths
|
缩短 APK 内的资源路径。 |
--resource-path-shortening-map path
|
指定路径,以便输出以下映射:将旧资源路径映射到缩短后的路径。 |
-v
|
提高输出的详细程度。 |
-h
|
显示工具帮助。 |
转换
默认情况下,AAPT compile
命令会将资源编译为适合 APK 的二进制格式。您还可通过指定 --proto-format
,以指定适合 AAB 文件的 protobuf 格式。convert
命令可在这两种格式之间转换 APK。
转换语法
使用 convert
的一般语法如下:
aapt2 convert -o output-file options file[,file[..]]
以下示例会转换 input.apk
中的资源,并在包含 protobuf 格式资源的 output.apk
中创建一个新 APK。它使用更紧凑的二进制搜索树替换通常的平面表格表示法,可以让 APK 体量更小,但检索性能会下降:
aapt2 convert -o output.apk --output-format proto --enable-sparse-encoding input.apk
转换选项
将以下选项与 convert
搭配使用:
表 7. 转换选项
选项 | 说明 |
---|---|
-o path
|
指定链接的资源 APK 的输出路径。 这是一个必需的标记,因为您必须指定可以存放链接资源的输出 APK 的路径。 |
--output-format [proto|binary]
|
输出的格式。可接受的值为 proto 和 binary 。如果未设置,则默认为 binary 。
|
--enable-sparse-encoding
|
允许使用二进制搜索树对稀疏条目进行编码。 此选项有助于优化 APK 大小,但会降低资源检索性能。 |
--keep-raw-values
|
保留 XML 文件中的原始属性值。 |
-v
|
提高输出的详细程度。 |
-h
|
显示工具帮助。 |
守护程序模式
AAPT 2.19 版本引入了用于发出命令的守护程序模式。守护程序模式允许您在单个 AAPT 会话中输入多个命令。
守护程序语法
使用以下命令启动守护程序模式:
aapt2 daemon
守护程序模式运行后,您可以输入命令。该命令的每个参数都必须单独占一行,并且命令的末尾有一个空行。按 Ctrl+D 可退出守护程序模式。
不妨使用以下单个 compile
命令:
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 daemon Ready compile project_root/module_root/src/main/res/values-en/strings.xml -o compiled/ Done compile project_root/module_root/src/main/res/drawable/myImage.png -o compiled/ Done ^D Exiting daemon
守护程序模式选项
守护程序模式的单一选项是 --trace-folder folder
,它会生成指向指定 folder 的 systrace
JSON 跟踪记录 fragment。
版本
使用 version
命令确定您使用的 AAPT2 版本:
aapt2 version Android Asset Packaging Tool (aapt) 2.19-8678579
使用 AAPT2 时的行为变化
在 AAPT2 之前,AAPT 是 Android 资源打包工具的默认版本,现在已被废弃。虽然 AAPT2 应该直接就可以处理旧版项目,但本节介绍了一些您应该注意的行为变化。
Android 清单中的元素层次结构
在以前的 AAPT 版本中,嵌套在 AndroidManifest.xml
文件中的错误节点上的元素会被忽略或引发警告。例如,考虑以下示例:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myname.myapplication"> <application ... <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <action android:name="android.intent.action.CUSTOM" /> </activity> </application> </manifest>
以前的 AAPT 版本直接忽略错误放置的 <action>
标记。
使用 AAPT2 时,您会收到以下错误:
AndroidManifest.xml:15: error: unknown element <action> found.
如需解决该问题,请确保您的清单元素正确嵌套。如需了解详情,请阅读应用清单概览。
资源声明
您无法再从 name
属性中指明资源类型。以下示例未按正确方式声明 attr
资源项目:
<style name="childStyle" parent="parentStyle"> <item name="attr/my_attr">@color/pink</item> </style>
采用此方式声明资源类型会导致以下编译错误:
Error: style attribute 'attr/attr/my_attr (aka my.package:attr/attr/my_attr)' not found.
如需解决此错误,请使用 type="attr"
明确声明资源类型:
<style name="childStyle" parent="parentStyle"> <item type="attr" name="my_attr">@color/pink</item> </style>
此外,在声明 <style>
元素时,其父项也必须为样式资源类型。否则,您将会遇到类似于以下内容的错误:
Error: (...) invalid resource type 'attr' for parent of style
@ 资源引用符号的误用
当您遗漏或错误放置资源引用符号 (@
) 时,AAPT2 会抛出构建错误。例如,当您指定样式属性时,如果遗漏了该符号:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> ... <!-- Note the missing '@' symbol when specifying the resource type. --> <item name="colorPrimary">color/colorPrimary</item> </style>
在构建模块时,AAPT2 会抛出以下构建错误:
ERROR: expected color but got (raw string) color/colorPrimary
此外,当您访问 android
命名空间中的资源时,如果错误地添加了该符号:
... <!-- When referencing resources from the 'android' namespace, omit the '@' symbol. --> <item name="@android:windowEnterAnimation"/>
在构建模块时,AAPT2 会抛出以下构建错误:
Error: style attribute '@android:attr/windowEnterAnimation' not found
库配置不正确
如果您的应用依赖于使用旧版 Android SDK Build Tools 构建的第三方库,您的应用可能会在运行时崩溃,且不会显示任何错误或警告。之所以会发生此崩溃,可能是因为在创建库的过程中,将 R.java
字段声明为 final
,从而导致所有资源 ID 都被内嵌在该���的类中。
AAPT2 依赖于在构建应用时能够将 ID 重新分配给库资源。如果该库将这些 ID 视为 final
并将其内嵌在库 DEX 中,便会出现运行时不匹配的情况。
如需解决此错误,请与库创建者联系,以使用最新版本的 Android SDK Build Tools 重新构建该库,然后重新发布该库。