获取 gradle 构建的 aapt2 参数?

Der*_*rek 3 android gradle aapt aapt2

我有兴趣尝试使用 aapt2 从命令行编译 Android 应用程序。当我尝试执行该命令时,链接约束布局库时遇到问题aapt2 link。该程序从 Android studio/gradle 成功构建。如何让 gradle 命令行调用向我显示它正在运行的 aapt2 命令?

作为记录,我尝试运行 ./gradlew assembleDebug --debug,我所能看到的只是对 aapt2-proto 库的调用。

Iza*_*ska 6

链接

该命令会有点复杂,并且取决于很多因素(例如您的资源、项目的依赖项、使用的标志等),因此获取完整命令的最简单方法是实际“破坏”资源。
编辑res/values/strings.xml文件以包含:

<string name="incorrect">@string/idontexist</string>
Run Code Online (Sandbox Code Playgroud)

转到项目目录并运行“gradlew clean assembleDebug”。AAPT2 在链接期间将失败,Android Gradle 插件将打印出所使用的完整命令。
我使用的是 3.2.0-alpha13 版本,它为我提供了完整的命令:

error: failed linking references.
Command: <path>/.gradle/caches/transforms-1/files-1.1/aapt2-3.2.0-alpha13-4662957-linux.jar/cbe84ab07c48b199e5fe8d202dd5845e/aapt2-3.2.0-alpha13-4662957-linux/aapt2 link -I\
      <path>/Android/Sdk/platforms/android-27/android.jar\
      --manifest\
      <path>/AndroidStudioProjects/Library/app/build/intermediates/merged_manifests/debug/processDebugManifest/merged/AndroidManifest.xml\
      -o\
      <path>/AndroidStudioProjects/Library/app/build/intermediates/processed_res/debug/processDebugResources/out/resources-debug.ap_\
      -R\
      @<path>/AndroidStudioProjects/Library/app/build/intermediates/incremental/processDebugResources/resources-list-for-resources-debug.ap_.txt\
      --auto-add-overlay\
      --java\
      <path>/AndroidStudioProjects/Library/app/build/generated/not_namespaced_r_class_sources/debug/processDebugResources/r\
      --proguard-main-dex\
      <path>/AndroidStudioProjects/Library/app/build/intermediates/legacy_multidex_aapt_derived_proguard_rules/debug/processDebugResources/manifest_keep.txt\
      --custom-package\
      com.example.foo.bar\
      -0\
      apk\
      --output-text-symbols\
      <path>/AndroidStudioProjects/Library/app/build/intermediates/symbols/debug/R.txt\
      --no-version-vectors
Daemon:  AAPT2 aapt2-3.2.0-alpha13-4662957-linux Daemon #0
Run Code Online (Sandbox Code Playgroud)

此处用于 AAPT2 的标志:

  • -I : 平台的android.jar的路径
  • --manifest:清单文件(AGP 使用合并的清单,而不仅仅是源中的清单)
  • -o:输出文件
  • -R:资源。通常你会一个接一个地传递,但由于这里有很多,它们被写入一个文件,然后该文件被传递到 AAPT2 (这就是为什么路径前面有“@”符号)
  • --auto-add-overlay : 允许叠加
  • --java : R.java 的输出目录
  • --proguard-main-dex:主 dex 的 Proguard 规则的输出文件
  • --custom-package:R 类的包
  • -0:不压缩这些扩展
  • --output-text-symbols:R.txt 的输出文件
  • --no-version-vectors:矢量绘图没有自动版本控制

其他可能对您有用的标志:

  • -v:详细日志记录
  • -A:包含您想要放入 APK 文件中的资源的目录,它们不会被处理或压缩,只是按原样放入输出文件中
  • -h : 打印出帮助

编译

编译命令非常简单。您基本上告诉 AAPT2 要编译哪个单个文件以及在哪里输出它。

<path>aapt2 compile -o /path/to/output/dir /path/to/file/to/compile.xml
Run Code Online (Sandbox Code Playgroud)

编译的标志是:

  • -o : 编译后的文件放置的目录
  • --pseudo-localize:生成伪语言环境的源
  • --legacy:使 AAPT2 更加宽松,并将某些错误视为警告(就像 AAPT1 那样)
  • -v:详细日志记录
  • -h : 打印出帮助

要记住的一件事是,编译的文件是二进制 .flat 文件,输出名称基于输入名称和文件的父目录名称。这意味着如果输入文件是res/drawable-450dpi/img.png ,则输出文件将为drawable-450dpi_img.png.flat。编译的值文件的扩展名是“arsc.flat”,而不仅仅是“.flat”,因此文件res/values-en/strings.xml将被编译为values-en_strings.arsc.flat。这是由 AAPT2 自动完成的,因此您无需担心,但最好了解一下,以防您稍后需要找到编译后的文件。

关于编译的另一个有趣的事实是,它在记住输入文件是什么(以及 XML 文件的行号)方面非常有用,因此如果链接失败,错误将不会指向 .flat 文件,而是指向原始输入文件代替。