本文修改的aapt的源码为Android 6.0.0_r1版本
本文中的aapt源码查看和修改参照Android中如何修改编译的资源ID值(默认值是0x7F…可以随意改成0x02~0x7E)和Android aapt实现资源分区(补充携程aapt源码)这两篇博客。本文主要是记录修改过程和编译aapt模块的命令。
源码查看
aapt的源码在所在的目录:Android/frameworks/base/tools/aapt/。
Main.cpp位置:android-6.0.0_r1/frameworks/base/tools/aapt/Main.cpp
首先查看Main.cpp的main方法:
int main(int argc, char* const argv[])
{
char *prog = argv[0];
Bundle bundle;
bool wantUsage = false;
int result = 1; // pessimistically assume an error.
...
//进行资源打包的参数p或package
else if (argv[1][0] == 'p')
bundle.setCommand(kCommandPackage);
...
/*
* Pull out flags. We support "-fv" and "-f -v".
*/
while (argc && argv[0][0] == '-') {
/* flag(s) found */
const char* cp = argv[0] +1;
while (*cp != '\0') {
...
//收集appt命令输入的参数,这些参数以"-"开头
case '-':
if (strcmp(cp, "-debug-mode") == 0) {
bundle.setDebugMode(true);
}
...
break;
default:
fprintf(stderr, "ERROR: Unknown flag '-%c'\n", *cp);
wantUsage = true;
goto bail;
}
cp++;
}
argc--;
argv++;
}
/*
* We're past the flags. The rest all goes straight in.
*/
bundle.setFileSpec(argv, argc);
//根据bundle收集的参数进行资源处理
result = handleCommand(&bundle);
//输入参数错误时会跳转到此
bail:
if (wantUsage) {
usage();
result = 2;
}
return result;
}
在main函数内,首先创建一个Bundle对象,这个对象用来存储输入的操作类型和相关的参数。argv相当于java中的字符串数组。取该数组的第2个字符串的第一个char值。因为是执行资源打包,所以它是’p’。bundle记录执行类型为kCommandPackage,即资源打包。while循环处理剩余的char数组(即字符串数组),将参数按照类型设置到bundle中。参数解析完毕,则会执行handleCommand(&bundle)
。如果在解析输入的参数时出现了错误,便使用goto跳转到bail代码块。在bail代码块中可能会执行usage();
,这个方法会打印出aapt所有的命令类型和相关的参数。
先看看usage()函数,省略了与资源打包无关的信息。
void usage(void)
{
...
fprintf(stderr,
" %s p[ackage] [-d][-f][-m][-u][-v][-x][-z][-M AndroidManifest.xml] \\\n"
" [-0 extension [-0 extension ...]] [-g tolerance] [-j jarfile] \\\n"
" [--debug-mode] [--min-sdk-version VAL] [--target-sdk-version VAL] \\\n"
" [--app-version VAL] [--app-version-name TEXT] [--custom-package VAL] \\\n"
" [--rename-manifest-package PACKAGE] \\\n"
" [--rename-instrumentation-target-package PACKAGE] \\\n"
" [--utf16] [--auto-add-overlay] \\\n"
" [--max-res-version VAL] \\\n"
" [-I base-package [-I base-package ...]] \\\n"
" [-A asset-source-dir] [-G class-list-file] [-P public-definitions-file] \\\n"
" [-S resource-sources [-S resource-sources ...]] \\\n"
" [-F apk-file] [-J R-file-dir] \\\n"
" [--product product1,product2,...] \\\n"
" [-c CONFIGS] [--preferred-density DENSITY] \\\n"
" [--split CONFIGS [--split CONFIGS]] \\\n"
" [--feature-of package [--feature-after package]] \\\n"
" [raw-files-dir [raw-files-dir] ...] \\\n"
" [--output-text-symbols DIR]\n"
" [--apk-module moduleName]\n"
"\n"
" Package the android resources. It will read assets and resources that are\n"
" supplied with the -M -A -S or raw-files-dir arguments. The -J -P -F and -R\n"
" options control which files are output.\n\n"
, gProgName);
...
}
打印appt执行的操作类型和对应的参数。
先看看handleCommand()函数,
int handleCommand(Bundle* bundle)
{
switch (bundle->getCommand()) {
case kCommandV