ビルド バリアントを使用してさまざまなバージョンのアプリを作成する

1. はじめに

最終更新日: 2022 年 4 月 14 日

ビルド バリアントは、異なるバージョンのアプリを作成する際に便利です。たとえば、コンテンツが制限された無料版アプリと、コンテンツの多い有料版アプリを作成できます。API レベルまたは他のデバイスのバリエーションに基づいて、異なるデバイスをターゲットとするアプリの異なるバージョンをビルドすることもできます。

この Codelab では、ユニット 1: Kotlin の基礎で作成した Dice Roller アプリを変更し、「デモ版」と「完全版」という 2 つのバージョンを作成します。「完全版」にはサイコロの出目を文字で表示するテキスト ボックスが追加されるため、ユーザーはサイコロ画像だけに頼ることなく出目を確認できます。

前提となる知識

以下のとおりであることを前提としています。

  • Android の基本の学習パスウェイ 1~4 を修了していること。前提条件となる Codelab を実施するには、ユニット 1: Kotlin の基礎のパスウェイをご覧ください。
  • Android ビルドシステムについて全般的に理解していること。主要コンポーネントを理解するには、ビルドの概要をご覧ください。

学習内容

  • ビルド バリアントについて
  • ソースセットについて
  • ビルド バリアントとソースセットを使用してさまざまなバージョンのアプリを作成する方法
  • アプリ バリアントに固有のアプリ ID を付与する方法

作成するアプリの概要

この Codelab では、ユニット 1: Kotlin の基礎の学習パスウェイで作成した DiceRoller アプリを使用します。DiceRoller アプリには、サイコロの画像と、その下に [ROLL] ボタンがあります。ユーザーが [ROLL] をクリックするとサイコロが振られ、出目に応じて画像が変更されます。

追加のプロジェクト ファイルを作成し、次のようなコードを追加します。

  • アプリの「デモ版」と「完全版」のプロダクト フレーバーを作成する。
  • プロダクト フレーバーに対応する「デモ版」と「完全版」のソースセットを作成する。
  • 「完全版」アプリのレイアウトにボックスを追加する。
  • 完全版のボックスを、ユーザーが [ROLL] をクリックすると出目が表示されるように設定する。
  • アプリタイトルを「デモ版」向けと「完全版」向けにカスタマイズする。
  • アプリの「デモ版」と「完全版」に、固有のアプリ ID を付与する。

完全版のアプリは次のようになります。

動的なボックスを備えた DiceRoller アプリ。

必要なもの

2. 環境をセットアップする

コードを取得する

「ユニット 1: Kotlin の基礎」で完成させた DiceRoller アプリが手元にない場合は、GitHub からアプリコードをダウンロードしてください。

Android Studio でアプリコードをダウンロードして開く手順は次のとおりです。

  1. android-basics-kotlin-dice-roller-with-images-app-solution の GitHub リポジトリのホームページで、[Code] > [Download ZIP] をクリックします。
  2. ZIP ファイルをダウンロードしたら、Android Studio でプロジェクトを開き、[File] > [Open] をクリックします。プロンプトが表示されたら、Empty Activity を開始するか、以前のプロジェクトを開きます。ダウンロードしたプロジェクトを開くため、どちらでも構いません。
  3. ZIP ファイルをダウンロードした場所(Downloads フォルダなど)に移動し、ZIP ファイルを選択して [Open] をクリックします。

Project ビューを使用する

ビルド バリアントの作業を行うときは、[Project] ビューでプロジェクト ファイルを扱い、さまざまなバリアントのすべてのディレクトリを確認する必要があります。そのためには、Android Studio で [Project] ペインを開き、ビュータイプ メニュー(デフォルトでは [Android] ビューに設定されています)をクリックして、[Project] ビューを選択します。

3. ビルド バリアントについて

ビルド バリアントは、プロダクト フレーバーとビルドタイプの、異なる組み合わせの結果です。プロダクト フレーバーはユーザー向けの属性であり、ビルドタイプはデベロッパー向けの属性であると考えることができます。実際はビルド バリアントは直接設定するわけではなく、プロダクト フレーバーのセットとビルドタイプのセットを設定し、それによってビルド バリアントを決定します。

具体的には、ビルド バリアントはプロダクト フレーバーとビルドタイプのすべての組み合わせを表し、それに応じて <product-flavor><build-type> という名前が付けられます。たとえば、ビルドタイプが debugrelease であり、プロダクト フレーバーが demofull である場合、ビルド バリアントは次のようになります。

  • demoDebug
  • demoRelease
  • fullDebug
  • fullRelease

DiceRoller アプリのプロダクト フレーバーとビルドタイプを設定しましょう。

4. プロダクト フレーバーを設定する

プロダクト フレーバーは、通常はユーザーが利用可能なアプリ バージョンを表すという意味で、アプリのユーザー向けの属性です。アプリのデモ版と完全版を作成するには、2 つのプロダクト フレーバーを追加してフレーバー ディメンションに割り当てる必要があります。プロダクト フレーバーを追加するには、アプリレベルの build.gradle ファイルを開き([Project] ビューで [app] > [build.gradle])、次のコードを android {} ブロックに貼り付けます。

flavorDimensions "app_type"
productFlavors {
   demo {
       dimension "app_type"
         }
   full {
       dimension "app_type"
   }
}

このコードは次の処理を行います。

  • app_type というフレーバー ディメンションを作成する。
  • demo {} ブロックと full {} ブロックで表される 2 つのプロダクト フレーバーを作成する。
  • 2 つのプロダクト フレーバーを app_type ディメンションに割り当てる(フレーバー ディメンションが 1 つしかない場合は省略可)。

これは、プロダクト フレーバーを定義するために必要な基本的なコードです。この Codelab では、後ほど追加のオプションを使用します。

5. ビルドタイプを設定する

ビルドタイプは、通常は開発の段階(デバッグ、ベータ版、リリースなど)を表すという意味で、アプリの開発者向けの属性です。Android Studio が debugrelease という 2 つのビルドタイプを自動的に設定します。debug ビルドタイプはデバッグ用であり、release ビルドタイプは配布用です。

ビルドタイプの作成と設定変更を行うには、アプリレベルの build.gradle ファイルの buildTypes {} ブロックを編集します。デフォルトの buildTypes {} ブロックは次のようになっています。

buildTypes {
   release {
       minifyEnabled false
       proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
   }
}

release ビルドタイプのデフォルト設定を確認できます(この Codelab では minifyEnabled プロパティや proguardFiles プロパティについては説明しません)。debug ビルドタイプは、デフォルトではビルド構成ファイルに表示されませんが、debug {} ブロックを追加することで特定の設定を追加または変更できます。デフォルト設定は今回の目的に合っているため、そのままにしておきます。

6. Build Variants ツール ウィンドウを使用する

2 つのプロダクト フレーバーと 2 つのビルドタイプができました。これでどのようなビルド バリアントが作成されるのかを見てみましょう。Android Studio で新しいビルド バリアントを表示するには:

  1. ツールバーで Sync Project with Gradle Files ボタン 4e7fbf18152549d8.png をクリックします。ビルド構成ファイルを変更するたびに、Studio では、新しいビルド構成を保存してビルドエラーを確認できるように、ファイルを同期するよう求められます。
  2. [Build] > [Select Build Variant](または、[View] > [Tool Windows] > [Build Variants])をクリックして、[Build Variants] ウィンドウを表示します。
  3. [Active Build Variant] 列で [demoDebug] をクリックして、すべてのビルド バリアント(demoDebug、demoRelease、fullDebugfullRelease)を含むメニューを開きます。このメニューを使用して、さまざまなビルド バリアントを選択して実行し、テストします。

Active Build Variant メニューが表示された Build Variants ツール ウィンドウ。

demoDebug バリアントと fullDebug バリアントを実行します(release ビルドタイプに基づくバリアントを実行するには追加の設定が必要になるため、この Codelab では扱いません)。これまでのところ、ユーザーの観点から demoDebug バリアントと fullDebug バリアントは区別がつきません。

7. バリアントごとに異なる機能を作成する

デモ版と完全版のアプリを用意できました。完全版に機能を追加しましょう。

ソースセットを使用してプレミアム機能を追加する

full プロダクト フレーバーについて、出目を表示するボックスを追加し、ユーザーがサイコロの画像だけに頼ることなく出目を確認できるようにしましょう。このプレミアム機能を追加するために、ソースセットを使用します。ソースセットは、特定のビルドタイプ、プロダクト フレーバー、ビルド バリアント用のコンテンツが入っているディレクトリです。デフォルトの main ソースセット([app] > [src] > [main])には、すべてのビルド バリアントで共有するコンテンツが入っています。このデフォルトのコンテンツは、他のソースセットのコンテンツでオーバーライドできます。

main ソースセットの内容をオーバーライドし、追加する必要があるソースセットを決定する方法は、変更する対象によって異なります。

レイアウトや画像などのリソース([main] > [res] にあるもの)を変更する一般的な手順は次のとおりです。

  1. 変更するプロダクト フレーバーのソースセット(ディレクトリ)を作成します(このソースセットを作成する場所と方法については、次のセクションで説明します)。
  2. 変更するリソース ファイルをこの新しいソースセットに貼り付けて、更新します。Android Gradle プラグイン(AGP)は、新しいソースセットに依存するビルド バリアントをビルドするとき、main のリソースコードを新しいソースセットのリソースコードでオーバーライドします。

Java クラスまたは Kotlin クラス([main] > [java] にあるもの)の動作をオーバーライドする一般的な手順は次のとおりです。

  1. 変更するプロダクト フレーバーと、同じフレーバー ディメンションの他のすべてのプロダクト フレーバーについて、ソースセット(ディレクトリ)を作成します。
  2. 変更するファイルをすべてのプロダクト フレーバーのソースセットに貼り付け、変更するコピーを改変します。
  3. main ソースセットから元のファイルを削除します。

完全版のアプリに動的なボックスを追加するにあたり、次のように、プレミアム機能を 2 つの主な編集機能として考えることができます。

  • レイアウトのカスタマイズ: activity_main.xml ファイルを変更してボックスを追加します。
  • アプリの動作のカスタマイズ: MainActivity.kt ファイルを変更して、出目に応じてボックスの表示内容を変更します。

次のセクションでは、ソースセットを作成する場所と方法について説明します。

新しいソースセットの作成場所を決定する

Android Gradle プラグイン(AGP)は、ビルドタイプ、プロダクト フレーバー、ビルド バリアントごとにファイルを整理する方法を示します。MainActivity.kt ファイルに対する変更を含むプレミアム機能を full プロダクト フレーバーに追加するには、full フレーバーと demo フレーバーの両方について、ソースセットを作成します。こうしたソースセットを作成する場所を確認するには、Android Studio で次の手順に沿って操作します。

  1. IDE ウィンドウで [Gradle] をクリックします。
  2. [MyApplication] > [Tasks] > [android] に移動し、[sourceSets] をダブルクリックします。[Tasks] フォルダが表示されない場合は、[File] > [Settings] > [Experimental] をクリックして [Do not build Gradle task list during Gradle sync] チェックボックスをオフにし(macOS の場合は [Android Studio] > [Preferences] > [Experimental])、同期中に Gradle がタスクリストを作成するようにします。Gradle がタスクを実行すると、[Run] ウィンドウに出力が表示されます。
  3. このようにテキストモードで表示されない場合は、[Run] ウィンドウで「Toggle view82487fd4e011f105.png をクリックします。

[Run] ウィンドウに、次の出力が表示されます。

------------------------------------------------------------
Project ':app'
------------------------------------------------------------

...

debug
-----
Compile configuration: debugCompile
build.gradle name: android.sourceSets.debug
Java sources: [app/src/debug/java]
Kotlin sources: [app/src/debug/kotlin, app/src/debug/java]
Manifest file: app/src/debug/AndroidManifest.xml
Android resources: [app/src/debug/res]
Assets: [app/src/debug/assets]
AIDL sources: [app/src/debug/aidl]
RenderScript sources: [app/src/debug/rs]
JNI sources: [app/src/debug/jni]
JNI libraries: [app/src/debug/jniLibs]
Java-style resources: [app/src/debug/resources]

...

full
----
Compile configuration: fullCompile
build.gradle name: android.sourceSets.full
Java sources: [app/src/full/java]
Kotlin sources: [app/src/full/kotlin, app/src/full/java]
Manifest file: app/src/full/AndroidManifest.xml
Android resources: [app/src/full/res]
Assets: [app/src/full/assets]
AIDL sources: [app/src/full/aidl]
RenderScript sources: [app/src/full/rs]
JNI sources: [app/src/full/jni]
JNI libraries: [app/src/full/jniLibs]
Java-style resources: [app/src/full/resources]

「debug」のファイルパスのリストには、AGP が「debug」プロダクト フレーバーのアプリコードとリソースを探すデフォルトの場所が記載されています。同様に、「full」のファイルパスのリストには、AGP が「full」プロダクト フレーバーのコンテンツを探すデフォルトの場所が記載されています。

「Java sources」(Java クラスや Kotlin クラスなどのファイル用)と「Android resources」(レイアウトや画像などのファイル用)のファイルパスをメモしておきます。新しいソースセットの作成場所を確認できたので、ソースセットを作成し、プレミアム機能のコードを追加します。

完全版のレイアウトをカスタマイズする

完全版のアプリにボックスを追加する手順は次のとおりです。

まず、full ソースセットと Java リソース ディレクトリを作成します。

  1. [Project] ペインを開き、[Project] ビューを選択します。
  2. DiceRoller/app/src/ ディレクトリに移動します。
  3. src ディレクトリを右クリックし、[New] > [Directory] を選択します。
  4. [Gradle Source Sets] のメニューから [full/resources] を選択し、Enter キーを押します。

次に、main ソースセットの activity_main.xml ファイルを full ソースセットに貼り付けます。

  1. DiceRoller/app/src/main/res/ に移動します。
  2. activity_main.xml ファイルを右クリックし、[Copy] をクリックします。
  3. DiceRoller/app/src/full/res/ に移動します。
  4. res ディレクトリを右クリックし、[Paste] をクリックします。

次に、アプリの full フレーバーにボックスを追加するために、full ソースセットの activity_main.xml ファイルに次のコードを追加します。

<TextView
    android:id="@+id/resultTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="16sp"
    android:text="Result"
    app:layout_constraintBottom_toTopOf="@+id/button"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@id/imageView" />

アプリの fullDebugdemoDebug のビルド バリアントを実行します([Build Variants] ツール ウィンドウを使用して、実行するビルド バリアントを選択し、[Run] をクリックします)。fullDebug バリアント専用の新しいボックスが表示されます。ただし、まだ何の機能もありません。サイコロの出目に応じて変化するようにプログラムしましょう。

プレースホルダとしてボックスに「Result」と表示されている DiceRoller アプリ。

完全版の動作をカスタマイズする

完全版のアプリでは、ボックスにサイコロの出目が文字で表示されます。この動作をプログラムする手順は次のとおりです。

まず、full ソースセットの Java ソース ディレクトリを作成します。

  1. [Project] ビューの [Project] ペインで、DiceRoller/app/src/full ディレクトリに移動します。
  2. full ディレクトリを右クリックし、[New] > [Directory] を選択します。
  3. [Gradle Source Sets] メニューから [java] を選択し、Enter キーを押します。

次に、debug ソースセットと Java ソース ディレクトリを作成します。

  1. [Project] ビューの [Project] ペインで、DiceRoller/app/src ディレクトリに移動します。
  2. src ディレクトリを右クリックし、[New] > [Directory] を選択します。
  3. [Gradle Source Sets] メニューから [debug/java] を選択し、Enter キーを押します。

次に、DiceRoller/app/src/main/java ディレクトリに移動します。

  1. MainActivity.kt ファイルを full/java ディレクトリと debug/java ディレクトリの両方に貼り付けます。
  2. main ソースセットから java ディレクトリ(MainActivity.kt ファイルを含む)を削除します(java ディレクトリを右クリックして [Delete] をクリックします)。
  3. full ソースセットの MainActivity.kt ファイルで、次のコードを rollDice() メソッドに追加します。
// Update the result text view
val resultTextView: TextView = findViewById(R.id.resultTextView)
resultTextView.text = when (diceRoll) {
    1 -> "One"
    2 -> "Two"
    3 -> "Three"
    4 -> "Four"
    5 -> "Five"
    else -> "Six"
}

fullDebugdemoDebug のビルド バリアントを再度実行します。完全版のボックスにサイコロの出目が表示されます。

動的なボックスを備えた DiceRoller アプリ。

アプリタイトルを変更する

わかりやすくするために、使用しているアプリ バージョンをアプリタイトルに指定しましょう。この種の変更は、ソースセットなしで実施できます。アプリタイトルは、AndroidManifest.xml ファイルの label プロパティ([app] > [manifests] > [AndroidManifest.xml])で定義します。実行中のバリアントに応じて label の値を変更するには、AndroidManifest.xml ファイルを開き、ラベル行を次のように変更します。

android:label="${appLabel}"

これにより、変数 appLabel がアプリタイトルとして割り当てられます。

次に、appLabel の値を設定するか、デモ版のアプリのタイトルを変更するには、先ほど作成した demo {} ブロックに manifestPlaceholders 行を追加します。

demo {
   dimension "version"
   manifestPlaceholders = [appLabel: "Dice Roller - Demo"]
   applicationIdSuffix ".demo"
}

同様に、アプリの full フレーバーのタイトルを変更するには、full {} ブロックに別の manifestPlaceholders 行を追加します。

full {
   dimension "version"
   manifestPlaceholders = [appLabel: "Dice Roller - Full"]
   applicationIdSuffix ".full"
}

demoDebugfullDebug のバリアントを再度実行します。ビルド バリアントごとに異なるタイトルが表示されます。

動的なボックスを備えた DiceRoller アプリの完成形。

8. ビルド バリアントに固有のアプリ ID を付与する

アプリの APK または AAB をビルドすると、ビルドツールは、以下の例に示すようにアプリレベルの build.gradle ファイルの defaultConfig {} ブロックで定義されたアプリ ID をアプリにタグ付けします。ただし、アプリのさまざまなバージョン(「デモ版」や「完全版」など)を作成し、Google Play ストアで別々の掲載情報として表示する場合は、ビルド バリアントごとに異なるアプリ ID を付与する必要があります。productFlavors {} ブロック内のフレーバーごとに、applicationId プロパティを再定義できます。または、以下の例に示すように applicationIdSuffix を使用してデフォルトのアプリ ID にセグメントを付加できます。

defaultConfig {
   applicationId "com.example.diceroller"
   ...
}

flavorDimensions "version"
productFlavors {
   demo {
 dimension "version"
       manifestPlaceholders = [appLabel: "Dice Roller - Demo"]
         applicationIdSuffix ".demo"
   }
   full {
       dimension "version"
       manifestPlaceholders = [appLabel: "Dice Roller - Full"]
         applicationIdSuffix ".full"
   }
}

9. 完了

これで、ビルド バリアントを使用して DiceRoller アプリの 2 つのバージョンを作成できました。

プロダクト フレーバーとビルドタイプを設定して、ビルド バリアントを作成しました。ソースセットを使用して「完全版」のアプリにプレミアム機能を追加しました。各ビルド バリアントに固有のアプリ ID を付与し、Play ストアで別々のアプリと見なされるようにする方法を学習しました。

さまざまなユーザー グループに適切に対応できるように、複数のアプリ バージョンを作成するために必要な基本的な手順を学習しました。

次のステップ

リファレンス ドキュメント