Build Variant — Androidにおけるbuild typeとproduct flavorとは

著者: IT Sectr 公開日: 2026-05-30 読了時間: 9 分

Android開発におけるBuild Variantとは、build typeとproduct flavorの組み合わせであり、APKまたはAABのビルド方法(パラメータ、リソース、コード)を決定します。各ビルドバリアントは、独自のapplicationId、署名キー、および依存関係を持つ独立したGradle設定を表します。Google Android Developers、2025によると、Build Variantsを適切に設定すると、各バリアントの不要なリソースを除外することで、ビルド時間を最大40%短縮できます。ビルドバリアントシステムは、最新のAndroidプロジェクトにおける設定管理の基盤です。

重要なポイント

  • Build Variant — 1つのBuild Typeと1つのProduct Flavorの組み合わせ。
  • Build Typeはビルドモード(debugまたはrelease)を定義します。
  • Product Flavorはアプリのバージョン(free、paid、demo、enterprise)を定義します。
  • Gradleは各Build Variantのタスク(installやassembleを含む)を自動生成します。
  • リソースとコードは、対応するsource setsを介してバリアントごとに上書きできます。

Build Variantとは?

Build Variantとは、1つのBuild Typeと1つのProduct Flavorを組み合わせた結果です。プロジェクトでProduct Flavorsが定義されていない場合、Build VariantはBuild Typeと一致します。Gradleは、すべてのFlavorDimensions、Product Flavors、Build Typesのデカルト積として、バリアントの完全なセットを自動生成します。例えば、free/paidフレーバーとdebug/releaseタイプの場合、freeDebug、freeRelease、paidDebug、paidReleaseの4つのバリアントが作成されます。

各Build Variantには、<Flavor><Type>形式の独自の名前が付けられます(フレーバーは大文字で始まります)。Gradleはこのバリアント用に個別のタスク(assembleFreeDebug、installFreeDebug、bundleFreeRelease)を生成します。Android Studioでは、Build Variantsパネル(View → Tool Windows → Build Variants)からバリアントを切り替えられます。バリアントを選択すると、コンパイルされるコード、含まれるリソース、生成されるAPK/AABが変わります。

Build Variantsシステムは、次の3つの主要なタスクを解決します。異なる環境(dev/staging/production)の設定分離、アプリの複数バージョン(free/paid)の作成、ビルドのA/Bテスト。Build Variantsがない場合、開発者は手動でフラグや設定を切り替える必要があり、人的ミスが発生します。Gradle Inc.、2024の調査によると、Build Variantsを導入すると、3つ以上のデプロイ環境を持つプロジェクトでビルドエラーが60%削減されます。

Gradleがバリアントを生成する仕組み

AGP(Android Gradle Plugin)は、設定フェーズですべての組み合わせを計算します。プロジェクトに2つの次元があり、それぞれ2つと3つのフレーバーがある場合、Gradleは2 × 2 × 3 = 12の組み合わせを作成し、それにBuild Typesの数(通常2)を掛けます。各組み合わせには、一意の名前とタスクセットが与えられます。AGPは各バリアント用のsource setを自動追加します:src/freeDebug/src/paidRelease/、および一般化されたsrc/free/src/debug/。リソース読み取りの優先順位は、variant → flavor → type → mainです。

groovy
// 例:4つのBuild Variants
// flavorDimensions "version", "server"
// version: demo, prod
// server: mock, live
// buildTypes: debug, release
// 合計:2 × 2 × 2 = 8バリアント

android {
    flavorDimensions "version", "server"

    productFlavors {
        demo { dimension "version" }
        prod { dimension "version" }
        mock { dimension "server" }
        live { dimension "server" }
    }
}

Build TypeとProduct Flavorの違い

Build Typeはアプリケーションのビルド方法(デバッグ情報の有無、最適化の有無、署名)を定義します。Product Flavorはビルドするもの(製品のバージョン)を定義します。Build Typeはビルドメカニズム(debug、release、staging)です。Product Flavorは製品バリアント(free、paid、enterprise、demo)です。両方の概念は直交しており、任意のBuild Typeを任意のProduct Flavorに適用できます。

デフォルトのBuild Typesには、debug(debuggable=true、minification=false、signing=debug.keystore)とrelease(debuggable=false、minification=true、signing=production.keystore)が含まれます。デフォルトのProduct Flavorは1つで名前がありません(実質的にmain source set)。開発者は独自のBuild Types(例:debuggable=true、minification=trueの“staging”)や任意の数のProduct Flavorsを追加できます。もう1つの違いは、Build Typesは次元にグループ化できませんが、Product Flavorsはできることです。

主要な実践的な違い:build.gradleのdefaultConfigはすべてのVariantsに適用されますが、productFlavorsとbuildTypesで上書きできます。buildTypeに追加されたBuildConfigFieldはそのタイプのすべてのフレーバーで表示され、productFlavorに追加されたものはそのフレーバーのすべてのタイプで表示されます。両方でフィールドが定義されている場合、buildTypeが優先されます(チェーン内で最後に適用されます)。

比較表

特性Build TypeProduct Flavor
目的ビルド方法ビルド内容
debug、release、stagingfree、paid、demo、enterprise
デフォルトdebug + release1つ(main)
Source Setsrc/debug/、src/release/src/free/、src/paid/
次元なしflavorDimensions
適用順序flavorの後、上書きdefaultConfigの後
BuildConfigFieldflavorを上書きdefaultConfigを上書き

build.gradleでのBuild Variants設定

設定の優先順位

Build Variantsの設定は、モジュールレベルのbuild.gradleファイルのandroidブロックで行います。最初にbuildTypesをパラメータとともに宣言し、次にflavorDimensionsとproductFlavorsを宣言します。Gradleはこれらの宣言に基づいてバリアントを自動生成します。各バリアントはモジュールのdefaultConfigを継承し、指定されたフィールドを上書きします。宣言の順序は優先順位に影響します。buildTypesはproductFlavorsの後に適用されます。

Gradleスクリプトで特定のBuild Variantにアクセスするには、android.applicationVariants(アプリモジュールの場合)またはandroid.libraryVariants(ライブラリモジュールの場合)を使用します。これはコレクションであり、設定ランタイム時に各バリアントの設定を変更するために反復処理できます。例えば、“demo”という単語を含むすべてのバリアントにプログラムでbuildConfigFieldを追加できます。

Android Gradle Plugin 8.xは、ラムダを介してバリアントを設定するためのよりクリーンなAPIであるonVariantsのサポートを追加しました。古いAPI(variantOutput、variantFilter)は非推奨としてマークされています。ライブラリモジュールでは、onEachとともにonVariantsを使用することをお勧めします。variantOutputからonVariantsへの移行は、AGPを7.xから8.xにアップグレードする際の推奨手順です。

groovy
android {
    buildTypes {
        debug {
            debuggable true
            minification false
            signingConfig signingConfigs.debug
        }
        release {
            debuggable false
            minification true
            proguardFiles "proguard-rules.pro"
            signingConfig signingConfigs.release
        }
        staging {
            debuggable true
            minification true
            versionNameSuffix "-staging"
        }
    }

    flavorDimensions "tier", "region"

    productFlavors {
        free { dimension "tier" }
        paid { dimension "tier" }
        us { dimension "region" }
        eu { dimension "region" }
    }
}

android.onVariants { variant ->
    if (variant.name.contains("Demo")) {
        variant.setEnabled(false)
    }
}

Source Setsとリソースの上書き

各Build Variantには、独自のsource sets階層(ソースコード、リソース、マニフェストを含むディレクトリ)が与えられます。source setはsrc/<variantName>/(例:src/freeDebug/)に配置され、java/、res/、AndroidManifest.xml、assets/を含めることができます。バリアントのsource setにファイルが存在する場合、メインのsource set(src/main/)の同じ名前のファイルを上書きします。リソースについては、置き換えではなくマージが行われます。システムはアクティブなすべてのsource setsからリソースをマージし、バリアント固有のものを優先します。

Build Variantのsource setsは、チェーンで構築されます:src/main/src/flavor/src/type/src/flavorType/。例えば、paidReleaseの場合、最初にmain、次にpaid、次にrelease、最後にpaidReleaseが適用されます。後続の各source setは前のものを上書きします。つまり、src/release/res/values/strings.xmlsrc/paid/の同じ文字列を上書きしますが、src/paidRelease/res/はさらに優先度が高くなります。

バリアントにsource setsを使用することは、リソースをカスタマイズする推奨方法です。コード内でBuildConfig.FLAVORをチェックしてロジックを分岐する代わりに、異なるsource setsに異なるファイルを配置するだけです。例えば、free版とpaid版のアイコンはそれぞれsrc/free/res/src/paid/res/に配置し、異なる権限を持つAndroidManifestはsrc/free/AndroidManifest.xmlsrc/paid/AndroidManifest.xmlに配置します。これはよりクリーンで高速(リソースはコンパイル時に処理され、ランタイムチェック不要)かつ安全(コードのバグにより無料版に誤って有料機能を含めることがない)です。

マルチモジュールプロジェクトでのBuild Variant

マルチモジュールプロジェクトでは、各モジュール(ライブラリ)が独自のBuild Variantsを持つことができます。AGPはバリアントを自動同期します。アプリモジュールがpaidReleaseをビルドする場合、依存するすべてのライブラリもpaidReleaseに対応するバリアントでビルドされます。ライブラリにproduct flavorsがなく、アプリモジュールにある場合に問題が発生します。その場合、ライブラリは1回(タイプに応じてreleaseまたはdebug)ビルドされます。

ライブラリモジュールの場合、Build VariantはデフォルトでアプリモジュールのBuild Typeと一致します(ライブラリにはproduct flavorsがないため)。ライブラリがアプリモジュールのフレーバーに適応する必要がある場合、同じflavorDimensionsとproductFlavorsをライブラリで宣言する必要があります。AGPは正確な名前の一致でフレーバーを照合します。Gradleは、ルートプロジェクトでsubprojectsまたはConvention Pluginsを使用したビルド設定によるフレーバー同期を推奨しています。

AGP 8.1以降、ライブラリはmultiple variantsを公開できます。つまり、すべてのライブラリバリアントをmavenリポジトリに同時に公開できます。これにより、アプリモジュールが有料フレーバーを使用しているが、ライブラリが無料版でのみ公開されている場合の問題が解決されます。Multiple variants publishing(MVP)により、依存プロジェクトが必要なバリアントを自動的に選択できます。MVPを有効にするには、ライブラリのbuild.gradleにpublishing { multipleVariants { ... } }を追加します。

バリアントのフィルタリングと無効化

CI/CDによる動的フィルタリング

一部のBuild Variantsを無効にする必要がある場合があります。例えば、mockReleaseの組み合わせが意味をなさない場合(モックサーバーを本番環境に出すべきでない)などです。GradleはvariantFilterを提供します。これは、各バリアントのプロパティをチェックし、setIgnore(true)で無効化できるDSLブロックです。VariantFilterはタスク作成前の設定フェーズで適用されるため、無効化されたバリアントはassembleタスクやinstallタスクを生成しません。

フィルタリングはビルドの高速化にも役立ちます。プロジェクトに8つのバリアントがあるが、開発者が1つだけで作業している場合、残りの7つのバリアントも設定を通過します。variantFilterを使用すると、無効化されたバリアントはタスクを作成せず、6つ以上のフレーバー次元を持つプロジェクトの設定時間を30-50%削減します。CI/CDでは、コマンドラインパラメータ-PbuildOnly=paidReleaseで動的にバリアントをフィルタリングできます。

groovy
android {
    variantFilter { variant ->
        // release用のmockとproduction用のdemoを無効化
        def names = variant.flavors*.name
        def isMock = names.contains("mock")
        def isDemo = names.contains("demo")
        def isRelease = variant.buildType.name == "release"

        if ((isMock && isRelease) || (isDemo && !isMock)) {
            variant.setIgnore(true)
        }
    }
}

// パラメータによる動的フィルタリング
if (project.hasProperty("buildOnly")) {
    def target = project.property("buildOnly")
    android.variantFilter { variant ->
        variant.setIgnore(variant.name != target)
    }
}

よくある質問

Build Variantsはいくつ作成できますか?

制限はありませんが、Gradleはすべてのフレーバーとタイプのデカルト積を作成します。3つの次元にそれぞれ3つのフレーバーと3つのbuild typesがある場合、27のバリアントになります。バリアントが多すぎると設定が遅くなります。1つのモジュールでは10〜12個以下のバリアントにすることをお勧めします。

flavorDimensionsが必要な理由は?

flavorDimensionsはProduct Flavorsを独立した軸にグループ化します。例えば、“tier”次元(free、paid)と“region”次元(us、eu)です。次元がない場合、すべてのフレーバーは1つの軸に属し、Gradleはすべてから1つのフレーバーのみを選択します(free+usとpaid+euを別々のバリアントとして持つことはできません)。

バリアントのapplicationIdを上書きするには?

productFlavorまたはbuildTypeブロックでapplicationIdを指定します。例えば、無料版の場合:free { applicationId “com.example.app.free” }。マニフェストでは${applicationId}を使用します。Gradleが自動的に値を代入します。これにより、両方のバリアントを1つのデバイスにインストールできます。

iOSでBuild Variantsを使用できますか?

iOSでは、Build Variantsに相当するものはScheme + Configurationの組み合わせです。Xcode Schemesは、異なるパラメータを持つDebug/Release設定を通じて構成されます。複数バージョン(free/paid)の場合は、Build ConfigurationsとPreprocessor Macrosが使用されます。Androidでは、コンセプトがより形式化されており、Gradleに組み込まれています。

Build VariantはAPKサイズに影響しますか?

はい、各バリアントでAPKサイズが異なる場合があります。Debugビルドにはデバッグ情報、SDK、サポートされていないリソースが含まれます。minificationとresource shrinkingを使用したReleaseビルドは最小サイズになります。Product Flavorもサイズに影響します。有料ライブラリのない無料版は、それらのライブラリのサイズ分だけ有料版より小さくなります。

まとめ

  • Build Variant — ビルド設定を定義する1つのBuild Typeと1つのProduct Flavorの組み合わせ。
  • Build Typeはコンパイルモード(debug/release/staging)を制御し、Product Flavorは製品バージョン(free/paid)を制御します。
  • Source setsは、ビルドバリアントごとにコード、リソース、マニフェストを上書きできます。
  • VariantFilterは不要な組み合わせを無効にし、Gradle設定を30〜50%高速化します。
  • マルチモジュールプロジェクトでは、すべてのモジュール間でのフレーバー同期またはmultiple variants publishingが必要です。
  • BuildConfigFieldとsource setsは、バリアント間の動作をカスタマイズする2つのクリーンな方法です。
  • 推奨事項:1つのプロジェクトで10〜12個以上のバリアントを作成しないでください。次元を意味のある形でグループ化してください。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください