Android App Bundle の形式

Android App Bundle は Google Play にアップロードするファイル(ファイル拡張子は .aab)です。

App Bundle は、図 1 に示すように、アプリのコードとリソースをモジュールに整理した署名付きバイナリです。各モジュールのコードとリソースは APK に含まれるものと同様に構成されています。これらの各モジュールが、個別の APK として生成される場合もあるためです。Google Play は App Bundle を使用して、ベース APK、機能 APK、構成 APK、マルチ APK(分割 APK をサポートしないデバイス用)など、ユーザーに提供するさまざまな APK を生成します。青色のディレクトリ(drawable/values/lib/ ディレクトリなど)は、モジュールごとに構成 APK を作成するために Google Play が使用するコードとリソースを表します。

アプリは App Bundle によって、それぞれがモジュールを表すディレクトリに整理されます。各モジュール ディレクトリ内のコードとリソースは一般的な APK と同様に構成されています。

図 1. 1 つのベース モジュール、2 つの機能モジュール、2 つのアセットパックが含まれる Android App Bundle のコンテンツ

以下に、App Bundle のファイルとディレクトリの一部について詳細を説明します。

  • base/、feature1/、feature2/: これらの最上位ディレクトリは、アプリの各種モジュールを表します。アプリのベース モジュールは常に App Bundle の base ディレクトリにあります。ただし、各機能モジュールのディレクトリは、そのモジュールのマニフェストの split 属性で指定された名前になります。詳細については、機能モジュールのマニフェストをご覧ください。
  • asset_pack_1/、asset_pack_2/: グラフィックを多用する大型のアプリやゲームの場合、アセットをアセットパックにモジュール化できます。アセットパックはサイズの上限が大きいのでゲームに最適です。各アセットパックをいつ、どのようにデバイスにダウンロードするかは、インストール時、高速フォロー、オンデマンドの 3 つの配信モードによってカスタマイズできます。アセットパックはすべて Google Play でホストされ、配信されます。App Bundle にアセットパックを追加する方法について詳しくは、Play Asset Delivery についてをご覧ください。
  • BUNDLE-METADATA/: このディレクトリにはメタデータ ファイルが含まれます。このファイルには、ツールやアプリストアで利用できる情報が含まれます。このようなメタデータ ファイルに、ProGuard マッピングやアプリの DEX ファイルの全リストが含まれることもあります。このディレクトリ内のファイルは、アプリの APK にパッケージ化されません。
  • モジュール プロトコル バッファ(*.pb)ファイル: これらのファイルは、アプリストア(Google Play など)に対し、各アプリ モジュールの内容を説明するメタデータを提供します。たとえば、BundleConfig.pb は App Bundle のビルドに使用されたビルドツールのバージョンなど、バンドル自体に関する情報を提供します。native.pbresources.pb は、各モジュールのコードとリソースについて説明します。これは、Google Play でさまざまなデバイス設定向けに APK を最適化する場合に利用されます。
  • manifest/: APK とは異なり、App Bundle は各モジュールの AndroidManifest.xml ファイルをこの別個のディレクトリに保存します。
  • dex/: APK とは異なり、App Bundle は各モジュールの DEX ファイルをこの別個のディレクトリに保存します。
  • res/、lib/、assets/: これらのディレクトリは、一般的な APK でのディレクトリと同じです。App Bundle をアップロードすると、Google Play がこれらのディレクトリを検査し、ファイルのパスを維持したまま、対象のデバイス設定に応じたファイルのみをパッケージ化します。
  • root/: このディレクトリには、このディレクトリが配置されているモジュールを含めた APK のルートに後で再配置されるファイルが保存されます。たとえば、App Bundle の base/root/ ディレクトリには、Class.getResource() を使用してアプリが読み込む Java ベースのリソースが含まれることがあります。これらのファイルは、アプリのベース APK と、Google Play が生成するすべてのマルチ APK のルート ディレクトリに後で再配置されます。このディレクトリ内のパスも保持されます。つまり、ディレクトリとそのサブディレクトリも APK のルートに再配置されます。

分割 APK の概要

最適化されたアプリケーションを提供するための基本的なコンポーネントは、Android 5.0(API レベル 21)以上で利用できる分割 APK のメカニズムです。分割 APK は通常の APK と非常に類似しており、コンパイルされた DEX バイトコード、リソース、Android マニフェストが含まれています。ただし、Android プラットフォームでは、インストールされている複数の分割 APK を 1 つのアプリとして扱うことができます。つまり、共通のコードやリソースにアクセスできる複数の分割 APK をインストールし、1 つのインストール済みアプリとしてデバイスに表示できます。

分割 APK のメリットは、モノリシック APK(アプリがサポートするすべての機能とデバイス構成用のコードとリソースを含む APK)を小さな個別のパッケージに分割して、必要に応じてユーザーのデバイスにインストールできることです。

たとえば、ある分割 APK に少数のユーザーだけが必要とする追加機能のコードとリソースを含め、一方で別の分割 APK には特定の言語や画面密度専用のリソースを含めることが考えられます。こうした各分割 APK は、ユーザーがリクエストしたとき、またはデバイスが必要としたときにダウンロード、インストールされます。

以下では、さまざまなタイプの APK について説明します。これらの APK をまとめてデバイスにインストールして、アプリのフル機能を構成できます。こうした APK をサポートするアプリ プロジェクトの構成方法については、このページの後半のセクションで説明します。

  • ベース APK: この APK は、他のすべての分割 APK からアクセスできるコードとリソースを備え、アプリの基本機能を提供します。ユーザーがアプリのダウンロードをリクエストすると、この APK が最初にダウンロード、インストールされます。ベース APK のマニフェストにのみ、アプリのサービス、コンテンツ プロバイダ、権限、プラットフォームのバージョン要件、システム機能に対する依存関係が完全に記述されているためです。Google Play がプロジェクトのアプリ モジュール(またはベース モジュール)からアプリのベース APK を生成します。アプリの初回ダウンロード サイズの削減について検討する場合は、このモジュール内のコードとリソースがすべてアプリのベース APK に含まれている点に留意することが重要です。
  • 構成 APK: これらの各 APK には、特定の画面密度、CPU アーキテクチャ、または言語用のネイティブ ライブラリとリソースが含まれます。ユーザーがアプリをダウンロードすると、ユーザーのデバイスを対象とする構成 APK のみがダウンロード、インストールされます。各構成 APK はベース APK または機能モジュール APK の依存関係です。そのため、構成 APK はコードとリソースを提供する APK とともにダウンロード、インストールされます。ベース モジュールおよび機能モジュールとは異なり、構成 APK 用には個別のモジュールは作成しません。標準的な方法でベース モジュールと機能モジュールに構成固有の代替リソースを作成する場合は、Google Play が自動的に構成 APK を生成します
  • 機能モジュール APK: これらの各 APK には、機能モジュールを使用してモジュール化したアプリの各機能のコードとリソースが含まれます。次に、その機能をデバイスにダウンロードするタイミングと方法をカスタマイズできます。たとえば、Play Core Library を使用すると、ベース APK をデバイスにインストールした後、オンデマンドで機能をインストールして、ユーザーに追加の機能を提供できます。たとえばあるチャットアプリで、写真を撮って送信する機能を、ユーザーがリクエストする場合にのみ、ダウンロードしてインストールすることが考えられます。機能モジュールはインストール時には利用できないという可能性もあるため、共通で使用するコードやリソースはベース APK に格納する必要があります。つまり、機能モジュールでは、インストール時にベース APK のコードとリソースのみが使用可能であることを想定する必要があります。アプリの機能モジュール APK は、プロジェクトの機能モジュールから Google Play によって生成されます。

機能モジュールが 3 つあり、複数のデバイス設定をサポートしているアプリについて考えます。以下の図 1 に、このアプリのさまざまな APK の依存関係ツリーを示します。ベース APK がツリーのルートを形成し、その他の APK はすべてベース APK に依存します(これらの APK のモジュールが Android App Bundle でどのように表されるのかについて関心をお持ちの場合は、Android App Bundle 形式をご覧ください)。

ベース APK はツリーのルートを形成し、機能モジュール APK はベース APK に依存します。依存関係ツリーのリーフノードを形成する構成 APK には、ベース APK とそれぞれの機能モジュール APK のデバイス設定に応じたコードとリソースが含まれます。

図 1. 分割 APK を使用して配信されるアプリの依存関係ツリー

これらの APK をご自分でビルドする必要はありません。Android Studio でビルドした署名済みの 1 つの App Bundle から、Google Play が APK をビルドします。App Bundle 形式とそのビルド方法について詳しくは、Android App Bundle のビルド、デプロイ、アップロードをご覧ください。

Android 4.4(API レベル 19)以前を搭載するデバイス

Android 4.4(API レベル 19)以前を搭載するデバイスは、分割 APK のダウンロードとインストールに対応していないため、代わりに Google Play がデバイスに単一の APK を配信します。これは、「マルチ APK」と呼ばれ、デバイスの構成に合わせて最適化されています。このマルチ APK がアプリのフル機能を表しますが、他の画面密度や CPU アーキテクチャ用のコードとリソースなどの不要なものは含まれません。

ただし、マルチ APK には、アプリがサポートするすべての言語のリソースが含まれます。それによって、たとえばユーザーがアプリの使用言語の設定を変更しても、別のマルチ APK をダウンロードする必要はありません。

マルチ APK には機能モジュールを後からオンデマンドでダウンロードする機能はありません。この APK に機能モジュールを含めるには、機能モジュールの作成時に、オンデマンドを無効にするか、融合を有効にする必要があります。

App Bundle を使用すると、アプリがサポートするデバイス設定ごとに APK のビルド、署名、アップロード、管理を行う必要がなくなります。アプリ全体で 1 つの App Bundle をビルドし、アップロードするだけで、後は Google Play に任せることができます。したがって、Android 4.4 以前を搭載するデバイスをサポートする計画の有無を問わず、Google Play はデベロッパーとユーザーの両方に対して柔軟な配信メカニズムを備えています。

ユーザーの言語の変更

App Bundle の場合、デバイスはアプリの実行に必要なコードとリソースのみをダウンロードします。したがって、言語リソースについては、デバイスの設定で現在選択されている 1 つ以上の言語と一致するアプリの言語リソースのみがユーザーのデバイスにダウンロードされます。

ユーザーがデバイスの設定で言語を切り替えた場合、アプリを新しい言語で表示するには、Google Play で追加の分割 APK のダウンロードとインストールが必要になることがあります。

Google Play は、切り替え直後に追加の言語をダウンロードしようとします。ユーザーのデバイスがオフラインの場合、ダウンロードが失敗した場合、またはリソースが多すぎる場合、Google Play はデバイスがもっと好ましい状況になったときにバックグラウンドでダウンロードを再試行します。Android 9.0(API レベル 28)以前のデバイスでは、新しい言語の分割 APK のインストール中にアプリがフォアグラウンドにある場合、アプリは強制終了されます。

アプリですべての言語をいつでもデバイスで使用できるようにする必要がある場合は、ビルド構成で言語の分割を無効にできます。

デバイスの設定で選択されているユーザーの言語とは別に、追加の言語をアプリのためにダウンロードする必要がある場合(たとえばアプリ内言語選択ツールを実装する場合)は、Play Core Library を使用してオンデマンドで言語をダウンロードできます。