置顶:
https://developer.android.google.cn/studio/command-line/aapt2
AAPT2
AAPT2 (Android Asset Packaging Tool)是一个构建工具,用来编译和打包app资源。
一般在AS和Android gradle插件中集成使用,
#单独下载SDK Build Tool,在命令行中
sdkmanager "build-tools;<buildToolsVersion>"
AAPT2位置在SDK Build Tool 26.0.2以后的 android_sdk/build-tools/version/ 目录中找到。
因为AAPT2更新不快,所以目录中的可能不是最新的,获取方法:
- 进入 https://dl.google.com/dl/android/maven2/index.html
- 找到 com.android.tools.build > aapt2 最新版本名
- 然后替换下述链接的所有
<aapt2-version>
, 并选择系统 https://dl.google.com/dl/android/maven2/com/android/tools/build/aapt2/<aapt2-version>/aapt2-<aapt2-version>-[windows | linux | osx].jar
AAPT2经过解析、排序(indexes)、编译,会把资源编译成一个根据Android平台优化过的二进制格式文件
增量编译
AAPT2支持增量编译,主要是通过两步实现:
- Compile: 将资源文件以二进制形式编译
- Link: 合并所有合并后的文件再打包
这样实现后,文件的变化粒度更小。
compile
AAPT2 支持Android所有资源类型,包括drawables 和xml.
调用AAPT2编译时,需要一次一个文件作为输入,解析并输出.flat 拓展名的二进制文件
如果使用–dir 传入资源目录,由于粒度不够,就无法更好享受增量编译了。
在 res/values/ 目录下的xml ,输出 资源表和 *.asrc.flat
除了 res/values/ 目录下的xml, 会被转化成二进制xml, 输出: *.flat
所有png 默认会被处理成 *.png.flat
语法
aapt2 compile <path-to-input-files> [options] -o <output-directory>
参数只记录可能用到的
参数 | 说明 |
---|---|
–pseudo-localize | 生成pseudo-localized版本的string |
–no-crunch | 禁用 PNG 处理(可以在debug的时候禁用加快编译速度) |
–legacy | 让AAPT警告,AAPT2报错的问题 变成警告(没必要就别开了) |
link
compile阶段产出的资源表,二进制xml,加工后的PNG,会在这个阶段被打包进apk
另外,apk中的辅助文件,如R.java, Proguard rule文件在这个阶段产生
这个阶段还不包括dex字节码,也未签名
如果不用gradlew 构建app,可以使用d8编译java字节码为dex字节码并且用apksigner签名apk
语法
aapt2 link <path-to-input-files> [options] -o <outputdirectory/outputfilename.apk> --manifest AndroidManifest.xml
#示例
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
参数只记录可能用到的
参数 | 说明 |
---|---|
-I | 需要提供平台的android.jar路径(提供Android命名空间,用于资源文件中的android:id),或者framework-res.apk用于某些构建功能 |
-A directory | 指定不被压缩的assets目录 |
–package-id package-id | 指定packageId,必须>=0x7f;或者min-sdk<=26时,使用–allow-reserved-package-id可以让id在0x02到0x7e |
–enable-sparse-encoding | Enables encoding of sparse entries using a binary search tree,可以优化apk大小,但是资源检索性能会降低 |
-z | Requires localization of strings marked ‘suggested’.(没讲作用) |
–proto-format | 修改资源格式为Protobuf,用于Android App Bundle |
–non-final-ids | 生成非final资源id |
-0 extension | 指定不被压缩的文件 |
dump
link生成的apk可以通过dump查看信息
aapt2 dump filename.apk [options]
相对于AAPT的改动
主要是对于一些错误,不再是忽略,而是直接报错
比如,在manifest中的action写错位置;引用style时漏写@;
特别说明
- style语法:
# 不能再用
<style name="foo" parent="bar">
<item name="attr/my_attr">@color/pink</item>
</style>
# 而要用
<style name="foo" parent="bar">
<item type="attr" name="my_attr">@color/pink</item>
</style>
- 属性语法
ForegroundLinearLayout 包含三个属性。
但是foregroundInsidePadding不属于android命名空间
以前会忽略android:foregroundInsidePadding,现在需要正确写入
- 依赖库错误
如果依赖了一个使用老版本Android SDK Build Tools 构建的第三方库,那么有可能造成无提示的运行时崩溃
可能原因:
在lib创建的时候,R.java中的变量被定义成final, 因此所有资源id会被内联到lib的class中
而AAPT2的功能,会重新赋值这些lib资源中的Id,然后就会导致class中内联的id没有找到修改前的id,继而崩溃
修复方式:重新获取一个新版本 Android SDK Build Tools 构建的第三方库