プレイ・フィーチャー・デリバリーの使用
フィーチャー・デリバリーとは?
Googleの開発者向けドキュメントには、この機能の詳細が記載されています。基本的に、開発者はGoogle Playストアがアプリのコンテンツを複数のダウンロード可能なパッケージに分割できるように、プロジェクトを構成することができます。また、コンテンツをユーザーに配信する方法を開発者がコントロールできるようになります。これらの分割されたソフトウェアとコンテンツのパッケージは、Android App Bundles(AAB)を使用してGoogle Playストアに配信されます。
プロジェクトの例FDMapLoader
このアプリは、要求されたときにユーザーに画像を提供するために再生機能配信を使用します。このアプリは、アプリのサイズ制限をテストするために200MBを超えるアプリを作成したり、大きなフィーチャーデリバリーモジュールを使用してダウンロードするように簡単に変更できます。
ビルドセットアップ
- fdwintermapmodule:のFeature Moduleプロジェクト。Qt Creator
- fdmaploader:のメインアプリプロジェクトQt Creator
- fdmaploader-android-project:Android App BundleをコンパイルするためのAndroidプロジェクト。
FDWintermapModuleのコンパイル - 機能モジュール
fdwintermapmoduleプロジェクトをQt Creator にロードし、ターゲットプラットフォーム用に設定し、ビルドします。
FDMapLoaderのコンパイル - メインアプリ
fdmaploaderをQt Creator にロードし、ターゲット・プラットフォーム用に設定し、ビルドします。
Androidプロジェクトの修正
- ビルドしたバイナリ(.so)ファイルを、機能モジュールとメインアプリのビルドディレクトリから、Androidプロジェクトの対応するライブラリディレクトリにコピーします。(それぞれ
app/src/main/jniLibs/[target ABI]/
とfdwintermapmodule/src/main/jniLibs/[target ABI]/
) - リソース・ファイルやJavaクラスなど、その他の変更ファイルをコピーする。(
.../res/...
と.../src/main/java/...
フォルダー) - Android Studioを使用するか、Gradleラッパーを使用してコマンドラインからAndroidプロジェクトをビルドする (
./gradlew
バンドル) - テストのために、バンドルからAPKを作成し、
bundletool
を使用してデバイスにローカルのテストバージョンをインストールすることができます。BundletoolはGoogleが提供するツールで、このドキュメントの後半でその使い方を説明します。テストとリリースのために、Google Play Console にバンドルをアップロードできます。
独自のコンテンツを追加する
この例は、開発者が独自のコンテンツを簡単に追加して Feature Delivery をテストできるように設計されています。Play ストアの最大パッケージサイズを超えるために、マップ画像 (マップ画像である必要はありませんが、この例のテーマに合っています。) を FDMapLoader と FDWintermapModule の images フォルダに追加できます。images.qrc
ファイルに画像名を追加する必要があります。
自分で作る
以下のセクションでは、プレイ機能配信を使用する独自のプロジェクトを作成する方法について説明します。例題をベースにすることをお勧めします。このプロジェクトでは、Qt 6.7.2 を使用しています。
機能モジュール
フィーチャーデリバリーは、通常の共有ライブラリーのようにC++ライブラリーを扱います。ライブラリを呼び出す前に、利用可能かどうかをチェックする必要があります。
- Qt Creator 、C++共有ライブラリを作成する。
- 機能を実装し、リソースを追加する。
- ビルドして.soバイナリを作成する。
メインアプリ (Qt)
- Qt Creator を使ってアプリを作成する(Qt Quick プロジェクトテンプレートを使用)。
- Feature Deliveryライブラリへのアクセスを実装する。Google Play Feature Delivery Javaライブラリの中心的なクラスは次のとおりです。
SplitInstallManager
. - Androidのテンプレートファイルは、QtCreatorProjects -> Build&Run -> [target ABI] -> Build Steps -> Build Android APK の「Create Templates」ボタンを使って作成できます。テンプレートは、プロジェクトの 'android' フォルダに作成されます。
- フォルダ
.../android/src/java/[package...]
に Java ファイルを追加し、ファイルパスをCMakeLists.txt
に追加します:qt_add_executable... ...[path]/[java-filename.java] ...
- この例では、呼び出しとコールバックを処理するJavaクラスが作成されています。Javaクラスは、JNIを使用してQtからアクセスされます。Androidのドキュメントには、モジュールを要求する方法についての簡単な説明があります。
- プロジェクトのandroidフォルダの下にJavaファイルを追加する場合、QT_ANDROID_PACKAGE_SOURCE_DIRプロパティを
CMakeLists.txt
:... set_property(TARGET appFDMainApp APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/android) ...
- また、メインアプリ
build.gradle
、機能APIの依存関係を持つ必要があります。implementation 'androidx.core:core:1.13.1'
を
implementation("com.google.android.play:feature-delivery:2.1.0")
- 機能モジュールが提供するライブラリへのアクセスを実装する。フィーチャー・モジュールはメイン・アプリで利用可能な場合もそうでない場合もあるため、モジュールはビルド時にリンクされず、モジュールへの呼び出しは実行時に解決されなければなりません。例
typedef void* (*LoadModuleRulesFunc)(); LoadModuleRulesFunc loadModuleRules = (LoadModuleRulesFunc) mFDModuleLibrary.resolve("loadModuleRules"); if (loadModuleRules) { void* result = loadModuleRules(); QScopedPointer<QString> resultStr{static_cast<QString*>(result)}; }
- メインアプリのユーザーインターフェースやその他の必要な部分を実装する。
機能モジュール(Qt)
- Qt Creator を使用してアプリを作成する(Qt C++ Library プロジェクトのテンプレートを使用)。
- モジュールが提供する機能を実装する。
Androidプロジェクト(Android)
機能提供のためのAndroidアプリバンドル構築のためのプロジェクト作成は、主にAndroidのドキュメントに基づいています:
手動またはAndroid Studioを使用してAndroidプロジェクトを作成します(「No Activity」テンプレートを使用)。プロジェクトは、トップレベルのプロジェクトと2つのサブプロジェクト、app
とfeature-module
を含むように変更されます。Android Studioテンプレートでは、app
サブプロジェクトが作成され、File -> New -> New Module テンプレートを使用してfeature-module
を追加できます。
テンプレート・プロジェクトにはいくつかの修正が必要です:
- メインレベル
build.gradle
に機能配信プラグインを追加します:plugins { id 'com.android.application' version '8.5.2' apply false id 'com.android.dynamic-feature' version '8.5.2' apply false id 'com.android.library' version '8.5.2' apply false }
settings.gradle
に機能モジュールを追加し、必要に応じてrootProject.name
を変更する:... rootProject.name = "name-of-the-root-project" include(:app) include(:name-of-the-feature-module)
app - サブプロジェクト
- Android プロジェクトでは、メイン App プロジェクトの Qt バイナリが必要です:
- Qt build:
[build directory]/android-build/libs/[target ABI]
にネイティブ・ライブラリをコピーします。app/src/main/jniLibs/[target ABI]
[build directory]/android-build/libs/
にある jar を以下にコピーします。app/libs/
- Qt build:
- Qt ビルドから、
res
フォルダ、AndroidManifest.xml
、local.properties
の内容も Android プロジェクトのそれぞれの場所にコピーします。 - 機能モジュール用の文字列を含むファイル
feature_names.xml
をapp/src/main/res/values
フォルダーに追加します:<?xml version="1.0" encoding="utf-8"?> <resources> <string name="feature_module_name">name-of-the-feature-module-here</string> </resources>
- ファイル
keep.xml
をapp/src/main/res/raw
フォルダーに追加します:<?xml version="1.0" encoding="utf-8"?> <resources xmlns:tools="http://schemas.android.com/tools" tools:keep="@string/feature_module_winter_map" tools:discard="" />
アプリのサブプロジェクトのビルドファイルの修正
Androidプロジェクトにコピーされたビルドファイルには、いくつかの修正が必要です。
app - サブプロジェクト
build.gradle
buildScript
とrepositories
ブロックを削除。- メインアプリの
build.gradle
にある Android ブロックは、若干の修正が必要です:defaultConfig
packagingOptions
dynamicFeatures
sourceSets
aaptOptions
dependencies
android { ... defaultConfig { ... applicationId "your-project-name-here" ... } packagingOptions.jniLibs.useLegacyPackaging true dynamicFeatures = [":your-dynamic-feature-name-here"] sourceSets { main { manifest.srcFile 'src/main/AndroidManifest.xml' java.srcDirs = [qtAndroidDir + '/src', 'src', 'java'] aidl.srcDirs = [qtAndroidDir + '/src', 'src', 'aidl'] res.srcDirs = [qtAndroidDir + '/res', 'res'] resources.srcDirs = ['resources'] renderscript.srcDirs = ['src'] assets.srcDirs = ['assets'] jniLibs.srcDirs = ['src/main/jniLibs/'] } } // Do not compress Qt binary resources file aaptOptions { noCompress 'rcc' } ... } dependencies { ... implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar']) implementation 'com.google.android.play:feature-delivery:2.1.0' implementation libs.material ... }
また、アンドロイド・ブロックに署名設定を追加する:
android { ... signingConfigs { release { store \code android { ... signingConfigs { release { storeFile file("/absolute/path/to/the/keystore.jks") storePassword "myStorePassword" keyAlias "myKeyAlias" keyPassword "myKeyPassword" } } buildTypes { release { signingConfig signingConfigs.release ... } } ... }
gradle.propertiesに追加します。
Qt はgradle.properties
にプロジェクト変数を追加しました。必要に応じてandroidPackageName
の値を変更してください。
AndroidManifest.xml
package
を削除します:... <manifest ... android:package... <--remove ... > ...
- 必要に応じて
label
とandroid.app.lib_name
を変更する:... <application ... android:label=" ... <activity ... > <meta-data android:name="android.app.lib_name" android:value=" ... /> ...
feature-module - サブプロジェクト
アプリと機能モジュールは、トップレベルのAndroidプロジェクトのサブプロジェクトとして作成されます。フォルダとファイルの構造は、アプリのサブプロジェクトと似ています。
- Qtビルドの機能モジュール・バイナリは、Qtサブプロジェクトにコピーされます。
[name-of-feature-module]/src/main/jniLibs/
- メイン・アプリと同様に、
src/main/res/
フォルダーには、qtprovider_paths.xml
とlibs.xml
をそれぞれ含むxml
とvalues
フォルダーがあるはずです。どちらのファイルも、アプリ・プロジェクトからコピーできます。 src/main/res/
フォルダーに drawable や mipmap のフォルダーがあり、その機能がそれらを必要としない場合は、それらを削除することができます。- フィーチャーモジュールの
src/main/res/values
には、app_name
フィールドを含めないでください。strings.xmlが他の用途で必要とされない単純なプロジェクトでは、削除することができます。 libs.xml
には、機能モジュールの名前だけが含まれます:... <array name="load_local_libs"> <item>name-of-the-feature-module-here</item> </array> <string name="static_init_classes"></string> <string name="use_local_qt_libs">0</string> <string name="bundle_local_qt_libs">0</string> ...
AndroidManifest.xml
は、 ディレクトリに追加されます:src/main/
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:dist="http://schemas.android.com/apk/distribution"> <dist:module dist:instant="false" dist:title="@string/feature_module_title_string"> <dist:delivery> <dist:on-demand /> </dist:delivery> <dist:fusing dist:include="false" /> </dist:module> <!-- This feature module does contain code. --> <application android:hasCode="true"/> </manifest>
- 機能モジュール
build.gradle
は、appプロジェクトのものとよく似ていますが、若干の変更が加えられています。以下はサンプル・プロジェクトの例です:plugins { id 'com.android.dynamic-feature' } dependencies { implementation project(':app') implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar']) implementation 'com.google.android.play:feature-delivery:2.1.0' } android { namespace = androidPackageName compileSdk = androidCompileSdkVersion ndkVersion androidNdkVersion // Extract native libraries from the APK packagingOptions.jniLibs.useLegacyPackaging true defaultConfig { resConfig "en" minSdkVersion qtMinSdkVersion targetSdkVersion qtTargetSdkVersion } sourceSets { main { manifest.srcFile 'src/main/AndroidManifest.xml' resources.srcDirs = ['resources'] renderscript.srcDirs = ['src'] assets.srcDirs = ['assets'] jniLibs.srcDirs = ['src/main/jniLibs/'] } } tasks.withType(JavaCompile) { options.incremental = true } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } lintOptions { abortOnError false } // Do not compress Qt binary resources file aaptOptions { noCompress 'rcc' } }
gradle.properties
ファイルをappサブプロジェクトからコピーし、 をフィーチャー・モジュール・パッケージに変更します。androidPackageName
ビルドとデプロイ
AAB バンドルは、gradle wrapper を使ってコマンドラインからビルドできます:./gradlew
bundle 作成された AAB はbuild/outputs/bundle/release
(またはdebug
) フォルダに入ります。このAABをGoogle Play Storeにコピーし、テスト用にリリースすることができます。--local-testing
パラメータを指定してbundletool
を使えば、ローカルでテストすることもできます。Bundletool ドキュメント
使用するBundletoolコマンド
- バンドルから APK:s を生成する:
bundletool build-apks --bundle=/path/to/bundle.aab --output=/path/to/apk/package.apks --local-testing
- 端末にアプリをインストールする:
bundletool install-apks --apks=/path/to/apk/package.apks
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.