Introduction to AAPT2:
- AAPT2 (Android Asset Packaging Tool) is a build tool used by Android Studio and the Android Gradle plugin to compile and package an app's resources. AAPT2 parses, indexes, and compiles resources into a binary format optimized for the Android platform.
- Android Gradle Plugin 3.0.0 and later enables AAPT2 by default,
- We can use the AAPT2 command line to compile link resources,
Usage scenario of aapt2 command line
- After using apktool for secondary package modification and fusion of code resource files, it is necessary to recompile the link to generate a resource index, that is, generate an R file. Before recompiling, use AAPT2 to compile (compile) and link (link) to generate an R.java file again. Use the javac and cvf commands of jdk to generate class and jar respectively, then use the dx or R8 command line tool to generate dex, and finally use the baksmali tool to generate samli files and merge them into the mother package smali, so that the real integration of resource files is achieved.
- We know that Android Studio can generate aab (Android App Bundle) files for Google Play to upload aab packages. It mainly uses the command line of the bundletool tool to encapsulate the command line, making it very simple to generate aab. If we use bundletool ourselves command line to generate aab files, then we need to use the --proto-format flag of AAPT2 to compile and link application resources, and generate protobuf (Google's protocol buffer format: Protocol Buffers | Google Developers ) list and resources . Then use the build-bundle command of bundletool to generate aab, and the generated aab can be uploaded to Google Play after signing with jarsigner
- If your application or game needs to be released overseas, you need to provide aab package, and the major domestic channels provide apk package, domestic generally aggregated channels, and then use packaging tools to produce specific channel packages, aggregated channels It is also possible to aggregate overseas channels. If overseas channels want to generate aab packages and use packaging tools instead of Andorid Studio to export packages, then AAPT2 is required. Before using bundletool to compress resources, use AAPT2 to generate a protobuf format list and resources on it
- How to view the apk information we generated, AAPT's dump command comes in handy to output information
dump
about the APK youlink
generated using the command - AAPT2 has stricter requirements on the format and grammar of resources. Where aapt reported warnings before, compiling under aapt2 may directly report errors, so we write codes and import resource files as standard as possible.
How to get AAPT2
- Generally, we
android_sdk/build-tools/version/
can find AAPT2 in the directory - The latest AAPT2 release can also be downloaded from Google's Maven repository
Summary of common commands of AAPT2
The following commands and usage instructions are from google's aapt2 documentation: AAPT2 | Android Developers | Android Developers
Later, I will use some commands to do some practice, solve some usage scenario problems we encountered above, and write another article
-
compile
- AAPT2 supports compiling all Android resource types such as drawables and XML files. When calling AAPT2 to compile, each call should pass a resource file as input. Then, AAPT2 will parse the file and generate an
.flat
intermediate binary file with the extension . This method is generally used for incremental compilation, and the speed is very fast. The packaging in AS should use this method. We can also use--dir
tags to include multiple The resource directory of resource files is passed to AAPT2 to compile all files in the directory and specify the output file as .zip -
The type of output file may vary depending on the input you provide for compilation. The table below illustrates this:
enter output XML resource files (such as String and Style ), which are located res/values/
in the directory.The resource table with *.arsc.flat
the extension.All other resource files. res/values/
All files except those under the directory will be converted to binary XML*.flat
files with the extension . Also, by default, all PNG files are compressed and have*.png.flat
an extension. If you choose not to compress PNGs, you can use options during compilation--no-crunch
.The files output by AAPT2 are not executables, you have to add these binaries as input later in the linking phase to generate the APK. However, the resulting APK file is not a ready-to-deploy executable on an Android device because it does not contain a DEX file (compiled bytecode) and is not signed.
-
Compilation syntax: aapt2 compile path-to-input-files [options] -o output-directory/
compile options
You can use several options with
compile
the command, as shown in the following table:options illustrate -o path
Specifies the output path for compiled resources. This is a required flag because you must specify the path to a directory where AAPT2 can output and store compiled resources.
--dir directory
Specifies the directories to search for resources in. While you can use this flag to compile multiple resource files with a single command, it loses the benefits of incremental compilation and is not recommended for large projects.
--pseudo-localize
Generate pseudo-localized versions of default strings , such as en-XA and en-XB. --no-crunch
Disable PNG processing. Use this option if you have worked with PNG files, or if you want to create a debug build that does not require file size reduction. Enabling this option speeds up execution, but increases output file size.
--legacy
Treat errors allowed when using earlier versions of AAPT as warnings. This flag should be used for unexpected compile-time errors. To address known behavior changes you may encounter when using AAPT2, see Behavior Changes in AAPT2 .
-v
Enable verbose logging. -
Link
During the linking phase, AAPT2 combines all intermediate files generated during the compilation phase (such as resource tables, binary XML files, and processed PNG files) and packages them into one APK. In addition, other auxiliary files such as and ProGuard rules files are generated at this stage
R.java
. However, the resulting APK does not contain DEX bytecode and is not signed. That is, you cannot deploy this APK to a device. If you don't use the Android Gradle plugin to build your app from the command line , you can use other command line tools, such as using d8 to compile Java bytecode to DEX bytecode, and apksigner to sign APKs.link syntax
The general syntax used
link
is as follows:aapt2 link path-to-input-files [options] -o outputdirectory/outputfilename.apk --manifest AndroidManifest.xml
In the following example, AAPT2 merges two intermediate files (
drawable_Image.flat
andvalues_values.arsc.flat
) with the file.AndroidManifest.xml
AAPT2android.jar
links the results against the file containing the resources defined in the Android package: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 options
You can
link
use the following options with the command:options illustrate -o path
Specifies the output path of the linked resource APK. This is a required flag because you must specify a path to the output APK where the linked assets can be placed.
--manifest file
Specifies the path to the Android manifest file to build. This is a required flag because the manifest file contains basic information about your app (such as the package name and app ID).
-I
Provides framework-res.apk
the path to the platform's android.jar or other APKs such as , which may be useful when building features.You must use this tag if you want to use attributes withandroid
namespaces (for example ) in resource files .android:id
-A directory
Specifies the asset catalog to include in the APK. You can use this directory to store unprocessed raw files. For more information, see Accessing raw files .
-R file
Pass a single .flat file to link, using overlay
semantics, not<add-resource>
markup.If you provide a resource file that overlaps (extends or modifies) an existing file, the last conflicting resource provided will be used.
--package-id package-id
Specifies the bundle ID to use for the app. Unless
--allow-reserved-package-id
used in conjunction with , you must specify a bundle ID greater than or equal to 0x7f.--allow-reserved-package-id
Allow reserved bundle IDs. Reserved bundle IDs are the IDs normally assigned to shared objects, ranging from 0x02 to 0x7e (inclusive). Using
--allow-reserved-package-id
, you can assign an ID that falls within the range of reserved bundle IDs.This option is only available for packages with a minimum SDK version of 26 or lower.
--java directory
Specifies the directory to build in R.java
.--proguard proguard_options
Generate output files for ProGuard rules. --proguard-conditional-keep-rules
Generate output files for ProGuard rules for the main dex. --no-auto-version
Disable automatic style and layout SDK versioning. --no-version-vectors
Disables automatic versioning of vector drawables. This option is only available if the APK was built using the vector drawable library. --no-version-transitions
Disable automatic versioning of transformed resources. This option is only available if the APK was built using the transform support library. --no-resource-deduping
Disable automatic removal of duplicate resources with the same value in compatible configurations. --enable-sparse-encoding
Allows encoding of sparse entries using binary search trees. This helps optimize APK size, but reduces resource retrieval performance. -z
Requires localization of strings marked "suggested". -c config
Provide a comma-separated list of configurations. 例如,如果您依赖于支持库(该支持库包含多种语言的翻译),则可以仅针对给定的语言配置(如英语或西班牙语)过滤资源。
您必须使用两个字母的 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
转储语法
使用
dump
的一般语法如下:aapt2 dump sub-command filename.apk [options]
转储子命令
您需要使用
dump
命令指定以下子命令之一:子命令 说明 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
提高输出的详细程度。 使用 AAPT2 时的行为变化
在 AAPT2 之前,AAPT 是 Android 资源打包工具的默认版本,现在已被弃用。虽然 AAPT2 应该直接就可以处理旧版项目,但本节介绍了一些您应该注意的行为变化。
Android 清单中的元素层次结构
在以前的 AAPT 版本中,嵌套在 Android 清单中的错误节点上的元素会被忽略或引发警告。例如,请参考以下示例:
<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="foo" parent="bar"> <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="foo" parent="bar"> <item type="attr" name="my_attr">@color/pink</item> </style>
此外,在声明
<style>
元素时,其父项也必须为样式资源类型。否则,您将会遇到类似于以下内容的错误:Error: (...) invalid resource type 'attr' for parent of style
带有 ForegroundLinearLayout 的 Android 命名空间
ForegroundLinearLayout
包含三个属性:foregroundInsidePadding
、android:foreground
和android:foregroundGravity
。请注意,与其他两个属性不同,foregroundInsidePadding
未包含在android
命名空间中。在以前的 AAPT 版本中,当您使用
android
命名空间定义foregroundInsidePadding
属性时,编译器会以静默方式忽略该属性。当使用 AAPT2 时,编译器会提前捕获该属性并引发以下编译错误:Error: (...) resource android:attr/foregroundInsidePadding is private
如需解决此问题,只需将
android:foregroundInsidePadding
替换为foregroundInsidePadding
。@ 资源引用符号的误用
当您遗漏或错误放置资源引用符号 (
@
) 时,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
库配置不正确
If your app depends on third-party libraries built with older versions of the Android SDK Build Tools , your app may crash at runtime without displaying any errors or warnings. This crash may occur because during library creation,
R.java
fields are declared as suchfinal
that all resource IDs are inlined in the library's class.AAPT2 relies on the ability to reassign IDs to library resources when building applications. If the library treats these IDs as
final
and embeds them in the library dex, there will be a runtime mismatch.To resolve this error, please contact the library creator to rebuild the library with the latest version of the Android SDK Build Tools and republish the library.