aapt2使用记录及技术点摘要

官方文档对aapt2的介绍:aapt2官方说明

转载参考自:https://blog.csdn.net/qq_43278826/article/details/86543932

转载参考自:使用aapt2 修改apk打包的资源id

 

aapt 是Android Asset Packaging
Tool的缩写,是编译和打包资源的工具。而aapt2是在aapt上做了优化。

Android Gradle Plugin 3.0.0或者更高版本默认开启aapt2。当然也可以在配置文件中手动关闭aapt2。在gradle.properties设置android.enableAapt2=false即可

aapt2将原先的资源编译打包过程拆分成了两部分,即编译和链接。
编译:将资源文件编译为二进制格式文件
链接:将编译后的所有文件合并,打包成一个单独文件

这种方式可以很好的提升资源的编译性能,比如只有一个资源文件发生改变时,你只需要重新编译改变的文件,然后将其与其他未改变的资源进行链接即可。而之前的aapt是将所有资源进行merge,merge完后将所有资源进行编译,产生一个资源ap_文件,该文件是一个压缩包,这样带来的后果就是即使只改变了一个资源文件,也要进行全量编译。

编译
aapt2支持编译所有的资源文件,并产生.flat格式的文件。

Input    output
res/values/目录下的xml文件    *.asrc.flat 格式的文件
其他资源文件    除 res/values/ 目录下的XML文件外,都是 *.flat格式文件. 此外所有的 PNG 文件默认压缩为 *.png.flat文件. 可以使用 --no-crunch 参数禁止压缩PNG图片
编译语法

aapt2 compile path-to-input-files [options] -o output-directory/
1
Compile 命令行参数

Option    Description
-o path    指定输出文件路径,若是不设置--dir directory,只是传了单个文件的path(path的需要严格按照这个格式path/resource-type[-config]/file存放,否则编译时会提示“bad resource path”),那么-o 后面的path设置为目录,若是设置--dir,则不必要再传入单个文件的path,同时-o后面的path应设置为文件名,比如:res.zip之类
--dir directory    指定扫描的资源目录
--no-crunch    禁止PNG图片压缩处理
-v    打开详细日志
举例
1)编译单个xml文件

aapt2 compile -v res/values/strings.xml -o out/



2)编译整个资源目录res

aapt2 compile -v --dir res -o res.zip



链接
在链接阶段,aapt2首先合并编译阶段生成的文件,像二进制XML文件,处理后的PNG文件等,然后,将其打包成一个apk文件。此外,在此阶段可以生成其他辅助文件,如R.java和ProGuard规则文件。当然,此时生成的apk文件并不包含dex文件,也没有签名。

链接语法

aapt2 link path-to-input-files [options] -o outputdirectory/outputfilename.apk --manifest AndroidManifest.xml
1
常用link命令行参数

Option    Description
-o path    指定输出文件路径
--manifest file    指定AndroidManifest文件路径
-I path    指定android.jar路径
-- emit-ids path    产生资源id映射文件名,可以适用于–stable-ids
--stable-ids    使用–emit-ids生成的文件,包含资源类型名称列表及其分配的ID。
--package-id package-id    指定生成资源索引表的packageID ,设置的packageID 必须大于或者等于0x7f。要是与 --allow-reserved-package-id联合使用就可以不受这个限制
--allow-reserved-package-id    允许设置packageId为 0x02 到 0x7e ,这个只适用最小版本是26及以下(注意:这个在buildToolVersion:28.0.3之后才有的)
--java directory    指定生成R.java的目录
-A directory    指定需要打包进apk的assets目录
-v    打开详细日志
举例
1)生成R.java放到build目录,生成资源id映射文件输出到当前目录ids.txt,同时设置packageID为0x50,res.zip为上一步编译得到的.flat压缩包

aapt2 link -I D:/Android/Sdk/platforms/android-27/android.jar  --allow-reserved-package-id  --package-id 0x50 --java build --emit-ids ids.txt -o res.apk --manifest AndroidManifest.xml res.zip
1
注意事项
要在AS 3.0 gradle中更好使用aapt2支持,请设置项目build.gradle的classpath为:

 classpath 'com.android.tools.build:gradle:3.2.1'
1
同时,gradle/gradle-wrapper.properties文件的distributionUrl设置为:

https\://services.gradle.org/distributions/gradle-4.8-all.zip
1
那么,也就可以在app的build.gradle设置aaptOptions:

aaptOptions {
    additionalParameters  "--allow-reserved-package-id", "--package-id"," 0x50"
}


在进行插件化开发时,如果插件apk含有res资源,宿主apk和插件apk在编译时都会产生自己的resources.arsc。由于打包后的宿主和插件apk资源id默认都是0x7f开头,那么它们的resources.arsc中的资源id必定是有相同的情况,会引起资源id冲突问题。

解决问题目前一共有两种思路:

1. 修改aapt源码,定制aapt工具,编译期间修改PP段。(PP字段是资源id的第一个字节,表示包空间)
DynamicAPK的做法就是如此,定制aapt,替换google的原始aapt,在编译的时候可以传入参数修改PP段:例如传入0x05编译得到的资源的PP段就是0x05。对于具体实现可以参考这篇博客https://blog.csdn.net/jiangwei0910410003/article/details/50820219

2. 修改aapt的产物,即,编译后期重新整理插件Apk的资源,编排ID。
VirtualApk采用的就是这个方案。对于具体实现可以参考这篇博客https://blog.csdn.net/weixin_43887839/article/details/86651232

 

这两种方式都有点麻烦,这两天忽然发现了aapt2支持一些新参数,其中有两个参数可以直接指定编译出apk的id范围:

–package-id package-id    指定生成资源索引表的packageID ,设置的packageID 必须大于或者等于0x7f。要是与 --allow-reserved-package-id联合使用就可以不受这个限制
–allow-reserved-package-id    允许设置packageId为 0x02 到 0x7e ,这个只适用最小版本是26及以下(注意:这个在buildToolVersion:28.0.3之后才有的)
例如在AS的app模块gradle文件中android括号内加上如下配置:

aaptOptions { 
additionalParameters '--allow-reserved-package-id','--package-id','0x70'
}
 

同时注意aapt2是开启状态,这样编译出来的apk resourceId就是0x70开头的了,与默认的0x7f区分开来。


  • aapt2 compile资源(编译res目录下的资源)
    --dir 编译的目录
    -o 编译生成的压缩包
    --legacy 将使用早期版本的 AAPT 时允许的错误视为警告
    aapt2 compile -o outRes.zip --dir res --legacy

    aapt2 compile (目标资源文件编译) 编译出对应flat文件
    aapt2 compile res/values/string.xml -o compiled/

  • aapt2 link
    aapt2 link (res,assets,AndroidManifest.xml资源,R文件生成)出apk包
    --auto-add-overlay 允许在叠加层中添加新资源,而不使用 标记
    -0 mp4 不想压缩mp4文件
    -R file 如果您提供与现有文件重叠(扩展或修改现有文件)的资源文件,系统会使用最后提供的冲突资源
    --java directory 指定要在其中生成 R.java 的目录。
    -I 提供平台的 android.jar 或其他 APK(如 framework-res.apk)的路径,这在构建功能时可能很有用。
    如果您要在资源文件中使用带有 android 命名空间(例如 android:id)的属性,则必须使用此标记
    aapt2 link -o outputfilename.apk res1.zip -R res2.zip -A assets -I android.jar -I constraint-layout-1.0.2.aar --manifest AndroidManifest.xml --auto-add-overlay -0 mp4 --java rdir

 

有疑问可以评论留言,看到会一起探讨解决办法。

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值