Google Play のアプリ配信モデルは、Android App Bundle を使用して、個別のユーザーのデバイス設定に合わせて最適化された APK を生成して配信します。これにより、ユーザーはアプリの実行に必要なコードとリソースのみをダウンロードできます。
Play Feature Delivery は App Bundle の高度な機能を使用することで、アプリの特定の機能を条件付きで配信する、またはオンデマンドでダウンロード可能にすることができます。そのためには、まず、これらの機能をベースアプリから機能モジュールに分離する必要があります。
機能モジュールのビルド構成
Android Studio を使用して新しい機能モジュールを作成すると、IDE はモジュールの build.gradle ファイルに次の Gradle プラグインを適用します。
// The following applies the dynamic-feature plugin to your feature module.
// The plugin includes the Gradle tasks and properties required to configure and build
// an app bundle that includes your feature module.
plugins {
id 'com.android.dynamic-feature'
}
標準のアプリ プラグインで使用できるプロパティの多くは、機能モジュールでも使用できます。以降のセクションでは、機能モジュールのビルド構成に含めるべきプロパティと含めるべきでないプロパティについて説明します。
機能モジュールのビルド構成に含めるべきでないプロパティ
各機能モジュールはベース モジュールに依存しているため、特定の構成も継承します。そのため、機能モジュールの build.gradle ファイルでは、以下を省略する必要があります。
- 署名設定: App Bundle はベース モジュールで指定する署名設定を使って署名されます。
minifyEnabledプロパティ: ベース モジュールのビルド構成からのみ、アプリ プロジェクト全体のコード圧縮を有効にすることができます。したがって、このプロパティを機能モジュールから除外する必要があります。ただし、機能モジュールごとに追加の ProGuard ルールを指定できます。versionCodeとversionName: App Bundle をビルドする際、Gradle はベース モジュールが提供するアプリ バージョン情報を使用します。これらのプロパティは、機能モジュールのbuild.gradleファイルから省略する必要があります。
ベース モジュールとの関係を確立する
Android Studio は、機能モジュールを作成するときに、以下に示すように、ベース モジュールの build.gradle ファイルに android.dynamicFeatures プロパティを追加して、ベース モジュールから機能モジュールを認識できるようにします。
// In the base module's build.gradle file.
android {
...
// Specifies feature modules that have a dependency on
// this base module.
dynamicFeatures = [":dynamic_feature", ":dynamic_feature2"]
}
また、下記のように、Android Studio は機能モジュールの依存関係としてベース モジュールも含めます。
// In the feature module's build.gradle file:
...
dependencies {
...
// Declares a dependency on the base module, ':app'.
implementation project(':app')
}
追加の ProGuard ルールを指定する
アプリ プロジェクトのコード圧縮を有効にできるのはベース モジュールのビルド構成のみですが、次のように proguardFiles プロパティを使用して、各機能モジュールにカスタム ProGuard ルールを指定できます。
android.buildTypes {
release {
// You must use the following property to specify additional ProGuard
// rules for feature modules.
proguardFiles 'proguard-rules-dynamic-features.pro'
}
}
これらの ProGuard ルールは、ビルド時に他のモジュール(ベース モジュールを含む)のルールと統合されます。したがって、機能モジュールごとに新しいルールセットを指定することはできますが、それらのルールはアプリ プロジェクト内のすべてのモジュールに適用されます。
アプリをデプロイする
機能モジュールをサポートするアプリの開発中も、通常のように、接続されたデバイスにアプリをデプロイできます。それには、メニューバーから [Run] > [Run] を選択します(またはツールバーで実行アイコン
をクリックします)。
アプリ プロジェクトに機能モジュールが含まれる場合、アプリのデプロイ時にどの機能を含めるかを選択できます。それには、次のようにして既存の実行 / デバッグ構成を変更します。
- メニューバーから [Run] > [Edit Configurations] を選択します。
- [Run/Debug Configurations] ダイアログの左パネルの [Android App] で該当するアプリの構成を選択します。
- [General] タブの [Dynamic features to deploy] で、アプリのデプロイ時に含める各機能モジュールのチェックボックスをオンにします。
- [OK] をクリックします。
デフォルトでは、Android Studio が App Bundle を使用してアプリをデプロイすることはありません。代わりに IDE が APK をビルドしてデバイスにインストールします。この APK は、サイズよりも、デプロイの早さについて最適化されます。IDE ではなく、Android Studio で App Bundle からの APK と Instant 版のビルド、デプロイを行うように構成するには、実行 / デバッグ構成を変更します。
機能モジュールをカスタム配信に使用する
機能モジュールの特長は、Android 5.0(API レベル 21)以上を搭載したデバイスに対して、アプリのさまざまな機能をどのように、どのタイミングでダウンロードするかをカスタマイズできるところにあります。たとえば、アプリの初回ダウンロード サイズを削減するために、一部の機能を必要に応じてオンデマンドでダウンロードしたり、特定の機能(写真の撮影機能、拡張現実のサポート機能など)を持つデバイスにのみダウンロードしたりするように構成できます。
アプリを App Bundle としてアップロードすると、デフォルトで高度に最適化されたダウンロードが実現されますが、より高度でカスタマイズ可能な機能配信オプションを使用するには、機能モジュールを使用してアプリの機能の追加構成とモジュール化を行う必要があります。つまり、機能モジュールは、必要に応じたダウンロードを可能にするモジュール式機能を作成するための構成要素を提供します。
オンライン ショップでユーザーが商品を売買するためのアプリについて考えてみましょう。アプリの以下の機能は、それぞれ別の機能モジュールに合理的にモジュール化できます。
- アカウントのログインと作成
- ショップのブラウジング
- 販売する商品の配置
- 支払いの処理
下の表は、機能モジュールがサポートするさまざまな配信方法と、それぞれサンプルのショップアプリの初回ダウンロード サイズをどのように最適化するかを示しています。
| 配信方法 | 動作 | ユースケース | 導入方法 |
|---|---|---|---|
| インストール時配信 | 上記の配信オプションのいずれも構成していない機能モジュールは、デフォルトでアプリのインストール時にダウンロードされます。これは、高度な配信方法を段階的に採用できることを意味するため、重要な動作です。たとえば、Play Feature Delivery Library を使用してオンデマンド ダウンロードを完全に実装した後にのみ、アプリ機能のモジュール化を活用して、オンデマンド配信を有効にできます。
さらに、アプリは後で機能のアンインストールをリクエストできます。 そのため、アプリのインストール時に特定の機能が必要で、その後は必要ない場合は、デバイスから機能を削除するようリクエストすることで、インストール サイズを削減できます。 |
ショップでの商品の売買方法に関するインタラクティブ ガイドのような特定のトレーニング アクティビティがアプリにある場合は、アプリのインストール時にデフォルトでその機能を含めることができます。 ただし、アプリのインストール サイズを小さくするために、ユーザーがトレーニングを完了した後に、アプリが機能の削除をリクエストできます。 |
高度な配信方法を構成しない機能モジュールを使用して、アプリをモジュール化します。 ユーザーが不要になった特定の機能モジュールを削除して、アプリのインストール サイズを削減する方法については、インストール済みモジュールを管理するをご覧ください。 |
| オンデマンド配信 | 必要に応じて機能モジュールをリクエストおよびダウンロードすることをアプリに許可します。 | ショップアプリの利用者のうち、販売する商品を投稿するユーザーが全体の 20% のみである場合、大多数のユーザー向けに初回ダウンロード サイズを削減する適切な戦略は、写真の撮影、商品の説明の投稿、販売する商品の掲載といった機能をオンデマンド ダウンロードとして利用可能にすることです。つまり、ユーザーがマーケットプレイスに商品を販売することに関心を示した場合にのみ、アプリの販売機能の機能モジュールをダウンロードするように設定できます。 さらに、ユーザーが一定期間後にアイテムを販売しなくなった場合、アプリは機能のアンインストールをリクエストすることで、インストール サイズを削減できます。 |
機能モジュールを作成して、オンデマンド配信を構成します。その後、アプリで Play Feature Delivery Library を使用して、オンデマンドでモジュールをダウンロードするようリクエストできます。 |
| 条件付き配信 | ハードウェア機能、言語 / 地域、最小 API レベルなど、特定のユーザー デバイス要件を指定して、アプリのインストール時にモジュール化された機能をダウンロードするかどうかを決定できます。 | ショップアプリがグローバル ユーザーを対象とする場合、一部の地域や言語でのみ頻繁に使用される支払い方法のサポートが必要になることがあります。アプリの初期ダウンロード サイズを削減するために、特定のタイプのお支払い方法を処理する機能モジュールを個別に作成し、登録された言語 / 地域に基づいてユーザーのデバイスに条件付きでインストールできます。 | 機能モジュールを作成して、条件付き配信を構成します。 |
| Instant 配信 | Google Play Instant を使用すると、デバイスにアプリをインストールしなくても、ユーザーがアプリを利用できるようになります。インストールする代わりに、ユーザーは Google Play ストアの [今すぐ試す] ボタン、またはデベロッパーが作成した URL を使用してアプリを利用できます。このコンテンツ配信形式を使用すると、Android アプリのユーザー エンゲージメントを高めるのが容易になります。 Instant 配信では、Google Play Instant を使用して、ユーザーがインストールせずにアプリの特定の機能をすぐに体験できるようにすることができます。 |
ゲームの最初のいくつかのレベルを軽量の機能モジュールに含める場合を考えてみましょう。このモジュールを Instant 対応にすると、ユーザーはアプリをインストールすることなく、URL リンクまたは [今すぐ試す] ボタンからすぐにゲームを試すことができます。 | 機能モジュールを作成して、Instant 配信を構成します。その後、アプリで Play Feature Delivery Library を使用して、オンデマンドでモジュールをダウンロードするようリクエストできます。
機能モジュールを使用したアプリ機能のモジュール化は最初のステップにすぎません。Google Play Instant をサポートするには、アプリのベース モジュールと Instant 対応にした特定の機能のダウンロード サイズが厳格なサイズ要件を満たす必要があります。詳しくは、アプリやゲームのサイズを縮小して Instant エクスペリエンスを有効にするをご覧ください。 |
リソースの URI の作成
URI を使用して機能モジュールに保存されているリソースにアクセスする場合は、Uri.Builder() を使用して機能モジュール リソース URI を生成します。
Kotlin
val uri = Uri.Builder()
.scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
.authority(context.getPackageName()) // Look up the resources in the application with its splits loaded
.appendPath(resources.getResourceTypeName(resId))
.appendPath(String.format("%s:%s",
resources.getResourcePackageName(resId), // Look up the dynamic resource in the split namespace.
resources.getResourceEntryName(resId)
))
.build()
Java
String uri = Uri.Builder()
.scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
.authority(context.getPackageName()) // Look up the resources in the application with its splits loaded
.appendPath(resources.getResourceTypeName(resId))
.appendPath(String.format("%s:%s",
resources.getResourcePackageName(resId), // Look up the dynamic resource in the split namespace.
resources.getResourceEntryName(resId)
))
.build().toString();
分割 APK が読み込まれた後に正しい名前空間が生成されるように、リソースへのパスの各部分は実行時に作成されます。
URI の生成方法の例として、次の名前のアプリと機能モジュールを考えてみましょう。
- アプリのパッケージ名:
com.example.my_app_package - 機能のリソース パッケージ名:
com.example.my_app_package.my_dynamic_feature
上記のコード スニペットの resId が、機能モジュール内の「my_video」という名前の未加工ファイル リソースを参照している場合、上記の Uri.Builder() コードは次のように出力されます。
android.resource://com.example.my_app_package/raw/com.example.my_app_package.my_dynamic_feature:my_video
この URI を使用して、アプリから機能モジュールのリソースにアクセスできます。
URI のパスを検証するには、APK Analyzer を使用して機能モジュール APK を検査し、パッケージ名を特定します。
機能モジュールについての検討事項
機能モジュールを使用すると、ビルド速度とエンジニアリング速度を向上させ、アプリの機能の配信を大幅にカスタマイズしてアプリのサイズを縮小できます。ただし、機能モジュールを使用する際には、いくつかの制約とエッジケースに注意する必要があります。
- 条件付き配信またはオンデマンド配信を使用して、1 台のデバイスに 50 個以上の機能モジュールをインストールすると、パフォーマンスの問題が発生する可能性があります。削除可能として構成されていないインストール時モジュールは、自動的にベース モジュールに含まれ、各デバイスで 1 つの機能モジュールとしてのみカウントされます。
- インストール時配信用に削除可能として構成するモジュールの数を 10 個以下に制限します。そうしないと、アプリのダウンロードとインストールに要する時間が増大する可能性があります。
- オンデマンドでの機能のダウンロードとインストールに対応しているのは、Android 5.0(API レベル 21)以上を搭載したデバイスのみです。それより前のバージョンの Android で機能を利用可能にするには、機能モジュールの作成時に融合を有効にしてください。
SplitCompatを有効にして、オンデマンドで配信されるダウンロード済みの機能モジュールにアプリがアクセスできるようにします。- 機能モジュールでは、
android:exportedをtrueに設定したアクティビティをマニフェストで指定しないでください。これは、別のアプリがアクティビティを起動しようとしたときに、デバイスが機能モジュールをダウンロードしたという保証がないためです。さらに、アプリは機能のコードとリソースにアクセスしようとする前に、その機能がダウンロード済みであることを確認する必要があります。詳細については、インストールしたモジュールの管理をご覧ください。 - Play Feature Delivery では、App Bundle を使用してアプリを公開する必要があるため、App Bundle の既知の問題を把握しておいてください。
機能モジュールのマニフェスト リファレンス
Android Studio を使用して新しい機能モジュールを作成する際、機能モジュールとして動作するモジュールに必要なほとんどのマニフェスト属性は IDE に含まれています。また、一部の属性はコンパイル時にビルドシステムによって挿入されるため、自分で指定または変更する必要はありません。次の表に、機能モジュールの重要なマニフェスト属性を示します。
| 属性 | 説明 |
|---|---|
| <manifest | これは一般的な <manifest> ブロックです。 |
| xmlns:dist="http://schemas.android.com/apk/distribution" | 新しい dist: XML 名前空間を指定します。これについては、以下で詳しく説明します。 |
| split="split_name" |
Android Studio が App Bundle をビルドする際、この属性が自動的に含まれます。そのため、この属性をご自分で指定または変更する必要はありません。
モジュールの名前を定義します。これは、Play Feature Delivery Library を使用してオンデマンド モジュールをリクエストする際に、アプリで指定するものです。 Gradle がこの属性の値を判断する方法: デフォルトでは、Android Studio を使用して機能モジュールを作成する際、IDE はモジュール名として指定された名前を、Gradle 設定ファイル内の Gradle サブプロジェクトとしてのモジュールを識別する名前として使用します。
App Bundle をビルドすると、Gradle はサブプロジェクト パスの最後の要素を使用して、このマニフェスト属性をモジュールのマニフェストに挿入します。たとえば、新しい機能モジュールを |
| android:isFeatureSplit="true | false"> |
Android Studio が App Bundle をビルドする際、この属性が自動的に含まれます。したがって、この属性を手動で指定または変更する必要はありません。
このモジュールが機能モジュールであることを指定します。ベース モジュールと構成 APK のマニフェストでは、この属性は省略するか、 |
| <dist:module | モジュールを APK としてパッケージ化して配布する方法を決定する属性を定義します。 |
| dist:instant="true | false" |
モジュールを Google Play Instant を介して Instant 機能として利用できるようにするかどうかを指定します。
アプリに Instant 対応の機能モジュールが含まれる場合は、ベース モジュールも Instant 対応にする必要があります。Android Studio 3.5 以上を使用して、Instant 対応の機能モジュールを作成すると、IDE が Instant 対応を自動的に有効にします。
|
| dist:title="@string/feature_name"> |
モジュールのユーザー向けのタイトルを指定します。たとえば、デバイスがダウンロードの確認を求める際にこのタイトルが表示される場合があります。 このタイトルの文字列リソースを、ベース モジュールの |
| <dist:fusing dist:include="true | false" /> |
Android 4.4(API レベル 20)以前を搭載したデバイスを対象とするマルチ APK 内に、対象のモジュールを含めるかどうかを指定します。
さらに、 |
| <dist:delivery> | 次に示すように、モジュール配信をカスタマイズするオプションをカプセル化します。各機能モジュールでは、以下のカスタム配信方法のうち 1 つのタイプのみを構成するようにしてください。 |
| <dist:install-time> |
モジュールをインストール時に利用可能にすることを指定します。これは、別のタイプのカスタム配信オプションを指定しない機能モジュールのデフォルトの動作です。 インストール時ダウンロードについて詳しくは、インストール時の配信を設定するをご覧ください。 このノードでは、デバイスの機能、ユーザーの居住国、最小 API レベルなど、特定の要件を満たすデバイスにモジュールを制限する条件も指定できます。詳細については、条件付き配信の構成をご覧ください。 |
| <dist:removable dist:value="true | false" /> |
未設定にするか、
デフォルトは 注: この機能は、Android Gradle プラグイン 4.2 を使用している場合か、コマンドラインから bundletool v1.0 を使用している場合にのみ使用できます。 |
| </dist:install-time> | |
| <dist:on-demand /> |
モジュールをオンデマンドでダウンロード可能にすることを指定します。つまり、モジュールはインストール時には利用できませんが、後でアプリがダウンロードをリクエストできます。
オンデマンド ダウンロードの詳細については、オンデマンド配信を構成するをご覧ください。 |
| </dist:delivery> | |
| </dist:module> | |
| <application
android:hasCode="true | false"> ... </application> |
DEX ファイルを生成しない機能モジュールの場合は、後で DEX ファイル形式にコンパイルされるコードが含まれていないため、以下のように設定する必要があります(そうしないとランタイム エラーが発生する可能性があります)。
|
| ... </manifest> |
参考情報
機能モジュールの使用の詳細については、以下のリソースをご覧ください。
ブログ投稿
- Google Play での開発、リリース、ビジネス拡大に役立つ新機能
- 追加言語 API をはじめとする最新の Android App Bundle のアップデート
- Plaid をモジュール化してみた
動画
利用規約とデータ セーフティ
Play Feature Delivery Library にアクセスするか、これを使用すると、Play Core ソフトウェア開発キット利用規約に同意したことになります。適用されるすべての利用規約とポリシーを読んで理解したうえで、ライブラリにアクセスしてください。
データ セーフティ
Play Core ライブラリは、Google Play ストアにおけるアプリのランタイム インターフェースです。そのため、アプリで Play Core を使用すると、Play ストア独自のプロセスが実行され、Google Play 利用規約に則ってデータが処理されます。ここでは、Play Core ライブラリがデータを処理して、アプリからの特定のリクエストを処理する方法について説明します。
追加言語 API
| 使用量について収集されたデータ | インストールされている言語のリスト |
| データ収集の目的 | 収集されたデータは、アプリのさまざまな言語のバージョンを提供し、アプリのアップデート後にインストール済みの言語を保持するために使用されます。 |
| データの暗号化 | データは暗号化されています。 |
| データ共有 | データが第三者に転送されることはありません。 |
| データの削除 | 一定の保持期間が経過するとデータが削除されます。 |
Play Feature Delivery
| 使用量について収集されたデータ |
デバイスのメタデータ アプリのバージョン |
| データ収集の目的 | 収集されたデータは、適切なモジュールをデバイスに配信し、更新やバックアップ、復元後にインストール済みのモジュールを保持するために使用されます。 |
| データの暗号化 | データは暗号化されています。 |
| データ共有 | データが第三者に転送されることはありません。 |
| データの削除 | 一定の保持期間が経過するとデータが削除されます。 |
Google はできる限り透明性を確保することを目指していますが、デベロッパーには、アプリによるユーザーデータの収集および共有とアプリのセキュリティ対策について Google Play のデータ セーフティ セクションのフォームに入力する責任があります。