AAPT2 コマンドラインの使用法の概要

AAPT2 の概要:

  • AAPT2 (Android Asset Packaging Tool) は、Android Studio および Android Gradle プラグインによってアプリのリソースをコンパイルおよびパッケージ化するために使用されるビルド ツールです。AAPT2 は、リソースを解析、インデックス付けし、Android プラットフォームに最適化されたバイナリ形式にコンパイルします。
  • Android Gradle Plugin 3.0.0 以降では、デフォルトで AAPT2 が有効になります。
  • AAPT2 コマンドラインを使用してリンクリソースをコンパイルできます。

aapt2コマンドラインの利用シナリオ

  • apktool を使用してセカンダリ パッケージの変更とコード リソース ファイルの融合を行った後、リンクを再コンパイルしてリソース インデックスを生成する、つまり R ファイルを生成する必要があります。再コンパイルする前に、AAPT2 を使用してコンパイル (コンパイル) とリンク (リンク) を行ってください。 R.java ファイルを再度生成します。jdk の javac コマンドと cvf コマンドを使用してクラスと jar をそれぞれ生成し、次に dx または R8 コマンド ライン ツールを使用して dex を生成し、最後に baksmali ツールを使用して samli ファイルを生成し、それらをマージします。これにより、リソース ファイルの実際の統合が実現されます。
  • Android Studio では、Google Play 用の aab (Android App Bundle) ファイルを生成して aab パッケージをアップロードできることがわかっています。主に、bundletool ツールのコマンド ラインを使用してコマンド ラインをカプセル化するため、aab の生成が非常に簡単になります。コマンド ラインで aab ファイルを生成し、次に AAPT2 の --proto-format フラグを使用してアプリケーション リソースをコンパイルおよびリンクし、protobuf (Google のプロトコル バッファ形式: Protocol Buffers | Google Developers ) リストとリソースを生成する必要があります。 Bundletool の build-bundle コマンドで aab を生成し、生成された aab は、jarsigner で署名した後に Google Play にアップロードできます。
  • アプリケーションやゲームを海外でリリースする必要がある場合は、aab パッケージを提供する必要があり、国内の主要チャネルは apk パッケージ、国内の一般的な集約チャネルを提供し、その後パッケージング ツールを使用して特定のチャネル パッケージ、集約チャネルを作成することも可能です。海外チャネルを集約します。海外チャネルが aab パッケージを生成し、Andorid Studio の代わりにパッケージ ツールを使用してパッケージをエクスポートする場合は、AAPT2 が必要です。bundletool を使用してリソースを圧縮する前に、AAPT2 を使用して protobuf 形式のリストとリソースを生成します。
  •  生成した APK 情報を表示する方法。AAPT の dump コマンドは、次のコマンドを使用して生成したdump APK に関する 情報を出力するのに便利です。link
  • AAPT2 では、リソースの形式と文法に関する要件がより厳しくなっており、以前は aapt が警告を報告していましたが、aapt2 でコンパイルすると直接エラーが報告される可能性があるため、可能な限り標準でコードを記述し、リソース ファイルをインポートしています。

AAPT2の入手方法

  • 通常、  android_sdk/build-tools/version/ AAPT2 は次のディレクトリにあります。
  • 最新の AAPT2 リリースは、Google の Maven リポジトリからダウンロードすることもできます。

AAPT2の共通コマンドまとめ

次のコマンドと使用手順は、Google の aapt2 ドキュメントからのものです: AAPT2 | Android Developers | Android Developers

後で、いくつかのコマンドを使用して練習し、上記で発生した使用シナリオの問題を解決し、別の記事を書きます。

  • コンパイル

  • AAPT2 は、 ドローアブルや XML ファイルなど、すべてのAndroid リソース タイプのコンパイルをサポートしています。AAPT2 を呼び出してコンパイルする場合、各呼び出しでリソース ファイルを入力として渡す必要があります。次に、AAPT2 はファイルを解析し、 .flat 拡張子が の中間バイナリ ファイルを生成します。この方法は通常、インクリメンタル コンパイルに使用され、速度は非常に高速です。AS のパッケージ化ではこの方法を使用する必要があります。タグを使用して複数のファイルを含めることもできます --dir 。リソース ファイルのリソース ディレクトリは AAPT2 に渡され、ディレクトリ内のすべてのファイルがコンパイルされ、出力ファイルが .zip として指定されます。
  • 出力ファイルのタイプは、コンパイルのために指定した入力によって異なる場合があります。以下の表はこれを示しています。

    入力 出力
    XML リソース ファイル ( String や Styleなど )。これらのファイルはres/values/ ディレクトリの下にあります 。 *.arsc.flat 拡張子が付いた リソース テーブル。
    他のすべてのリソース ファイル。  ディレクトリの下にあるファイルを除くすべてのファイルは、拡張子が のバイナリXML ファイルres/values/ に変換されます 。*.flatまた、デフォルトでは、すべての PNG ファイルは圧縮されており、 *.png.flat 拡張子が付いています。PNG を圧縮しないことを選択した場合は、コンパイル中にオプションを使用できます --no-crunch 。

    AAPT2 によって出力されるファイルは実行可能ファイルではないため、リンク フェーズの後半でこれらのバイナリを入力として追加して APK を生成する必要があります。ただし、生成された APK ファイルは、DEX ファイル (コンパイルされたバイトコード) を含まず、署名されていないため、Android デバイスにすぐに展開できる実行可能ファイルではありません。

  • コンパイル構文: aapt2 入力ファイルへのパスをコンパイルする [オプション] -o 出力ディレクトリ/

    コンパイルオプション

    compile 次の表に示すように、コマンドでは複数のオプションを使用できます 。

    オプション 説明する
    -o path コンパイルされたリソースの出力パスを指定します。

    AAPT2 がコンパイルされたリソースを出力および保存できるディレクトリへのパスを指定する必要があるため、これは必須のフラグです。

    --dir directory リソースを検索するディレクトリを指定します。

    このフラグを使用すると、1 つのコマンドで複数のリソース ファイルをコンパイルできますが、増分コンパイルの利点が失われるため、大規模なプロジェクトにはお勧めできません。

    --pseudo-localize en-XA や en-XB などのデフォルト文字列の擬似ローカライズされたバージョンを生成します。
    --no-crunch PNG 処理を無効にします。

    PNG ファイルを使用したことがある場合、またはファイル サイズの削減を必要としないデバッグ ビルドを作成する場合は、このオプションを使用します。このオプションを有効にすると、実行速度は向上しますが、出力ファイルのサイズは増加します。

    --legacy 以前のバージョンの AAPT を使用する場合に許可されるエラーを警告として扱います。

    このフラグは、予期しないコンパイル時エラーに使用する必要があります。AAPT2 の使用時に発生する可能性がある既知の動作の変更に対処するには、「  AAPT2 の動作の変更」を参照してください。

    -v 詳細ログを有効にします。
  • リンク フェーズでは、AAPT2 はコンパイル フェーズで生成されたすべての中間ファイル (リソース テーブル、バイナリ XML ファイル、処理された PNG ファイルなど) を結合し、1 つの APK にパッケージ化します。さらに、ProGuard ルール ファイルなどの他の補助ファイルもこの段階で生成されます R.java 。ただし、結果の APK には DEX バイトコードが含まれておらず、署名されていません。つまり、この APK をデバイスにデプロイすることはできません。Android Gradle プラグインを使用してコマンド ラインからアプリをビルドしない場合は、 d8を使用して Java バイトコードを DEX バイトコードにコンパイルしたり、  apksigner を 使用して APK に署名したりするなど、他のコマンド ライン ツールを使用できます 。

    使用される 一般的な構文はlink 次のとおりです。

    aapt2 入力ファイルへのリンク パス [オプション] -o
    出力ディレクトリ/出力ファイル名.apk --manifest AndroidManifest.xml
    

    次の例では、AAPT2 は2 つの中間ファイル (drawable_Image.flat と values_values.arsc.flat) をファイルに AndroidManifest.xml マージします。AAPT2 は、 android.jar 結果を Android パッケージで定義されたリソースを含むファイルにリンクします。

    aapt2 link -o Output.apk 
     -I android_sdk/platforms/android_version/android.jar
        コンパイル済み/res/values_values.arsc. flat
        コンパイル済み/res/drawable_Image. flat --manifest /path/to/AndroidManifest.xml -v
    

    link コマンドでは次のオプションを使用できます 。

    オプション 説明する
    -o path リンクされたリソース APK の出力パスを指定します。

    リンクされたアセットを配置できる出力 APK へのパスを指定する必要があるため、これは必須のフラグです。

    --manifest file ビルドする Android マニフェスト ファイルへのパスを指定します。

    マニフェスト ファイルにはアプリに関する基本情報 (パッケージ名やアプリ ID など) が含まれているため、これは必須のフラグです。

    -I framework-res.apkプラットフォームの android.jar または他の APK ( など) へのパスを提供します 。これは、機能を構築するときに役立つ可能性があります。

    リソース ファイル内で android (たとえば) 名前空間 を持つandroid:id属性を使用する場合は、このタグを使用する必要があります。
    -A directory APK に含めるアセット カタログを指定します。

    このディレクトリを使用して、未処理の生ファイルを保存できます。詳細については、「RAW ファイルへのアクセス」を参照してください。

    -R file overlay マークアップではなくセマンティクス を使用して、単一の . flat ファイルをリンクに渡します <add-resource> 。

    既存のファイルと重複する (拡張または変更する) リソース ファイルを指定すると、最後に指定された競合するリソースが使用されます。

    --package-id package-id アプリに使用するバンドル ID を指定します。

    と組み合わせて使用​​しない限り --allow-reserved-package-id 、0x7f 以上のバンドル ID を指定する必要があります。

    --allow-reserved-package-id 予約されたバンドル ID を許可します。

    予約済みバンドル ID は、通常、共有オブジェクトに割り当てられる ID で、範囲は 0x02 ~ 0x7e (両端の値を含む) です。を使用すると --allow-reserved-package-id、予約されたバンドル ID の範囲内にある ID を割り当てることができます。

    このオプションは、最小 SDK バージョンが 26 以下のパッケージでのみ使用できます。

    --java directory ビルドするディレクトリを指定します R.java 。
    --proguard proguard_options ProGuard ルールの出力ファイルを生成します。
    --proguard-conditional-keep-rules メイン dex の ProGuard ルールの出力ファイルを生成します。
    --no-auto-version スタイルとレイアウトの自動 SDK バージョン管理を無効にします。
    --no-version-vectors ベクター ドローアブルの自動バージョン管理を無効にします。このオプションは、APK がベクター ドローアブル ライブラリを使用してビルドされた場合にのみ使用できます。
    --no-version-transitions 変換されたリソースの自動バージョン管理を無効にします。このオプションは、APK が変換サポート ライブラリを使用して構築された場合にのみ使用できます。
    --no-resource-deduping 互換性のある構成で同じ値を持つ重複リソースの自動削除を無効にします。
    --enable-sparse-encoding 二分探索ツリーを使用したスパースエントリのエンコードを可能にします。これは APK サイズの最適化に役立ちますが、リソース取得パフォーマンスは低下します。
    -z 「推奨」とマークされた文字列のローカライズが必要です。
    -c config コンマ区切りの構成リストを指定します。

    例如,如果您依赖于支持库(该支持库包含多种语言的翻译),则可以仅针对给定的语言配置(如英语或西班牙语)过滤资源。

    您必须使用两个字母的 ISO 639-1 语言代码定义语言配置,后面可选择性地添加两个字母的 ISO 3166-1-alpha-2 区域代码(在区域代码前加上小写的“r”,例如 en-rUS)。

    --preferred-density density 允许 AAPT2 选择最相符的密度并移除其他所有密度。

    您可以在应用中使用多种像素密度限定符,如 ldpi、hdpi 和 xhdpi。在您指定首选密度后,AAPT2 会选择最相符的密度并将其存储在资源表中,然后移除其他所有密度。

    --output-to-dir 将 APK 内容输出到 -o 指定的目录中。

    如果您在使用此标记时遇到任何错误,可以通过升级到 Android SDK Build Tools 28.0.0 或更高版本来解决这些问题。

    --min-sdk-version min-sdk-version 设置要用于 AndroidManifest.xml 的默认最低 SDK 版本。
    --target-sdk-version target-sdk-version 设置要用于 AndroidManifest.xml 的默认目标 SDK 版本。
    --version-code version-code 指定没有版本代码时要注入 AndroidManifest.xml 中的版本代码(整数)。
    --compile-sdk-version-name compile-sdk-version-name 指定没有版本名称时要注入 AndroidManifest.xml 中的版本名称。
    --proto-format 以 Protobuf 格式生成已编译的资源。

    适合作为 bundle tool 的输入,用于生成 Android App Bundle。

    --non-final-ids 使用非最终资源 ID 生成 R.java(在 kotlinc/javac 编译期间,系统不会内嵌从应用的代码对这些 ID 的引用)。
    --emit-ids path 在给定的路径下生成一个文件,该文件包含资源类型的名称及其 ID 映射的列表。它适合与 --stable-ids 搭配使用。
    --stable-ids outputfilename.ext 使用通过 --emit-ids 生成的文件,该文件包含资源类型的名称以及为其分配的 ID 的列表。

    此选项可以让已分配的 ID 保持稳定,即使您在链接时删除了资源或添加了新资源也是如此。

    --custom-package package_name 指定要在其下生成 R.java 的自定义 Java 软件包。
    --extra-packages package_name 生成相同的 R.java 文件,但软件包名称不同。
    --add-javadoc-annotation annotation 向已生成的所有 Java 类添加 JavaDoc 注释。
    --output-text-symbols path 生成包含指定文件中 R 类的资源符号的文本文件。

    您必须指定输出文件的路径。

    --auto-add-overlay 允许在叠加层中添加新资源,而不使用 <add-resource> 标记。
    --rename-manifest-package manifest-package 重命名 AndroidManifest.xml 中的软件包。
    --rename-instrumentation-target-package instrumentation- target-package 更改插桩的目标软件包的名称。

    它应与 --rename-manifest-package 结合使用。

    -0 extension

    指定您不想压缩的文件的扩展名。

    --split path:config[,config[..]] 根据一组配置拆分资源,以生成另一个版本的 APK。

    您必须指定输出 APK 的路径和一组配置。

    -v 可提高输出的详细程度。

    转储

    dump 用于输出有关您使用 link 命令生成的 APK 的信息。例如,以下命令的输出结果为所指定 APK 的资源表中的内容:

    aapt2 dump resources output.apk
    

    转储语法

    使用 dump 的一般语法如下:

    aapt2 dump sub-command filename.apk [options]
    

    转储子命令

    您需要使用 dump 命令指定以下子命令之一:

    子命令 说明
    apc 输出在编译期间生成的 AAPT2 容器(APC)的内容。
    badging 输出从 APK 的清单中提取的信息。
    configurations 输出 APK 中的资源使用的每项配置。
    packagename 输出 APK 的软件包名称。
    permissions 输出从 APK 的清单提取的权限。
    strings 输出 APK 的资源表字符串池的内容。
    styleparents 输出 APK 中使用的样式的父项。
    resources 输出 APK 的资源表的内容。
    xmlstrings 输出 APK 的已编译 xml 中的字符串。
    xmltree 输出 APK 的已编译 xml 树。

    转储选项

    您可以将以下选项与 dump 搭配使用:

    选项 说明
    --no-values 禁止在显示资源时输出值。
    --file file 将文件指定为要从 APK 转储的参数。
    -v 提高输出的详细程度。

    使用 AAPT2 时的行为变化

    在 AAPT2 之前,AAPT 是 Android 资源打包工具的默认版本,现在已被弃用。虽然 AAPT2 应该直接就可以处理旧版项目,但本节介绍了一些您应该注意的行为变化。

    Android 清单中的元素层次结构

    在以前的 AAPT 版本中,嵌套在 Android 清单中的错误节点上的元素会被忽略或引发警告。例如,请参考以下示例:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="com.example.myname.myapplication">
       <application
           ...
           <activity android:name=".MainActivity">
               <intent-filter>
                   <action android:name="android.intent.action.MAIN" />
                   <category android:name="android.intent.category.LAUNCHER" />
               </intent-filter>
               <action android:name="android.intent.action.CUSTOM" />
           </activity>
       </application>
    </manifest>
    

    以前的 AAPT 版本直接忽略错误放置的 <action> 标记。但从 AAPT2 开始,会出现以下错误:

    AndroidManifest.xml:15: error: unknown element <action> found.
    

    如需解决该问题,请确保您的清单元素正确嵌套。如需了解详情,请参阅清单文件结构

    资源声明

    您无法再从 name 属性中指明资源类型。例如,以下示例未按正确方式声明 attr 资源项目:

    <style name="foo" parent="bar">
        <item name="attr/my_attr">@color/pink</item>
    </style>
    

    采用这种方式声明资源类型会导致以下构建错误:

    Error: style attribute 'attr/attr/my_attr (aka my.package:attr/attr/my_attr)'
    not found.
    

    如需解决此错误,请使用 type="attr" 明确声明资源类型:

    <style name="foo" parent="bar">
      <item type="attr" name="my_attr">@color/pink</item>
    </style>
    

    此外,在声明 <style> 元素时,其父项也必须为样式资源类型。否则,您将会遇到类似于以下内容的错误:

    Error: (...) invalid resource type 'attr' for parent of style
    

    带有 ForegroundLinearLayout 的 Android 命名空间

    ForegroundLinearLayout 包含三个属性:foregroundInsidePaddingandroid:foreground 和 android:foregroundGravity。请注意,与其他两个属性不同,foregroundInsidePadding 未包含在 android 命名空间中。

    在以前的 AAPT 版本中,当您使用 android 命名空间定义 foregroundInsidePadding 属性时,编译器会以静默方式忽略该属性。当使用 AAPT2 时,编译器会提前捕获该属性并引发以下编译错误:

    Error: (...) resource android:attr/foregroundInsidePadding is private
    

    如需解决此问题,只需将 android:foregroundInsidePadding 替换为 foregroundInsidePadding

    @ 资源引用符号的误用

    当您遗漏或错误放置资源引用符号 (@) 时,AAPT2 会抛出构建错误。例如,当您指定样式属性时,请注意是否遗漏了该符号,具体如下所示:

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
      ...
      <!-- Note the missing '@' symbol when specifying the resource type. -->
      <item name="colorPrimary">color/colorPrimary</item>
    </style>
    

    在构建模块时,AAPT2 会抛出以下构建错误:

    ERROR: expected color but got (raw string) color/colorPrimary
    

    此外,当您访问 android 命名空间中的资源时,请注意是否错误地添加了该符号,具体如下所示:

    ...
    <!-- When referencing resources from the 'android' namespace, omit the '@' symbol. -->
    <item name="@android:windowEnterAnimation"/>
    

    在构建模块时,AAPT2 会抛出以下构建错误:

    Error: style attribute '@android:attr/windowEnterAnimation' not found
    

    库配置不正确

    アプリが古いバージョンのAndroid SDK Build Toolsで構築されたサードパーティ ライブラリに依存している場合  、アプリは実行時にエラーや警告を表示せずにクラッシュする可能性があります。このクラッシュは、ライブラリの作成中に、すべてのリソース ID がライブラリのクラスにインライン化されるようにR.java フィールドが宣言されるために 発生する可能性があります 。final

    AAPT2 は、アプリケーションの構築時にライブラリ リソースに ID を再割り当てする機能に依存しています。ライブラリがこれらの ID を扱い final 、ライブラリ dex に埋め込むと、実行時に不一致が発生します。

    このエラーを解決するには、ライブラリの作成者に連絡して、最新バージョンの Android SDK Build Tools を使用してライブラリを再構築し、ライブラリを再公開してください。

おすすめ

転載: blog.csdn.net/qq_19942717/article/details/127709082