1术语和缩略词
- AAPT:Android Asset Packaging Tool,Android资源打包工具,将res文件夹所有的资源(layout\drawable\string\array等),asset下的资源,AndroidManifest.xml,Android.jar文件编译成为一个资源索引文件resource.arsc以及一个R.java类。asset下的资源不会编译,直接压缩进apk。
- AAPT2:Android Studio3.0后默认为AAPT2打包方式,在AAPT基础上为资源的增量编译提供了支持,功能更加完善。
- Gradle:是一款开源的自动化构建工具,使用灵活且性能极佳。
2背景
- 在插件化过程中,原来项目需要用到插件的资源,涉及到加载插件的资源,因为插件是以apk的方式存在的,所以插件的ID和原来项目的ID可能导致重复,为了解决这个问题,需要把插件的资源ID重新排一遍,才给宿主加载和使用。
- 过去使用Eclipse开发,使用的是aapt1的打包方案,在Eclipse中,publc.xml是aapt在打包资源时用来固定资源id的,如果资源在public.xml中有对应的id了,那么打包资源时就用已经有的id,因此只需要修改public.xml文件就可以完成固定资源ID。
- 现在使用Android Studio开发,android gradle plugin 从1.3.0开始忽略了public.xml,因此我们需要换一种方式固定资源ID,避免和原来项目资源ID冲突。
3资源冲突方案
3.1 AAPT2参数修改法
- aapt2支持一些新参数,其中有两个参数可以直接指定编译出apk的id范围:
| 命令 | 内容 |
|---|---|
| package-id | 指定生成资源索引表的packageID |
| allow-reserved-package-id | 最好设置packageId为 0x02 到 0x7f(实际测试中0x00-0xff全部可用) ,这个只适用最小版本是26及以下(注意:这个在buildToolVersion:28.0.3之后才有的) |
- 在app目录下的build.gradle中的android{}中添加以下内容,只能更改前四位
aaptOptions { additionalParameters '--allow-reserved-package-id','--package-id','0x10' }
- 编译完成后进入以下目录查看R.java文件有没有修改到对应的ID,有则全部成功。注意:Android Studio4.2以上(4.0和4.1可能也存在)在项目中无法找到R.java文件,需要打开项目所在文件夹,手动搜索文件。
3.2 AAPT2标记法
在aapt2的链接阶段中,查看相关的链接选项:
| 命令 | 内容 |
|---|---|
| --emit-ids path | 在给定的路径下生成一个文件,该文件包含资源类型的名称及其 ID 映射的列表。它适合与 --stable-ids 搭配使用 |
| --stable-ids | outputfilename.ext 使用通过 --emit-ids 生成的文件,该文件包含资源类型的名称以及为其分配的 ID 的列表。此选项可以让已分配的 ID 保持稳定,即使您在链接时删除了资源或添加了新资源也是如此 |
- 根据上面的选项内容,我们可以利用--emit-ids和--stable-ids命令搭配可以实现id的固定。
第一步:
在app目录下的build.gradle中的android{}中添加以下内容
` aaptOptions {
File publicTxtFile = project.rootProject.file('public.txt')
//public文件存在,则应用,不存在则生成
if (publicTxtFile.exists()) {
project.logger.error "${publicTxtFile} exists, apply it."
//aapt2添加--stable-ids参数应用
aaptOptions.additionalParameters("--stable-ids", "${publicTxtFile}")
} else {
project.logger.error "${publicTxtFile} not exists, generate it."
//aapt2添加--emit-ids参数生成
aaptOptions.additionalParameters("--emit-ids", "${publicTxtFile}")
}
}`
第二步:
-
项目Clean一下,然后编译,查看项目目录下是否出现public.txt文件,如果没有出现则第一步的脚本放错地方,如果有就打开public.txt文件,打开后,一键替换需要替换的资源ID。
-
注意:假如替换前4位则会报错,因为默认前四位只能是0x7f,因此最好只替换第5位,但这样的话同时只能存在15个插件,可以编写一个脚本将后5位改成由00001开始,每个资源ID加一的格式,对于一般的插件而言不会超过4位数,这样做的话第5和第6位都没有被占用,那么就可以同时存在最多240个插件。(假如想要修改前四位,可以添加方案一中的allow-reserved-package-id方法)
第三步:
- 再次编译,通过--stable-ids和根目录下的public.txt进行资源id的固定,编译完成后进入以下目录查看R.java文件有没有修改到对应的ID,有则全部成功。
- 注意:Android Studio4.2以上(4.0和4.1可能也存在)在项目中无法找到R.java文件,需要打开项目所在文件夹,手动搜索文件。
4总结
- AAPT2参数修改法毫无疑问比AAPT2标记法更加简单,但缺点也很明显,只能修改资源ID的前四位,但是能够已经能够保证同时240个插件存在而不冲突,而AAPT2标记法也有缺点,就是编译的步骤多,而且编译有时候有问题,需要重新清理删除再编译。