【Android Studio】Product Flavorで環境を切り分ける方法!
この記事からわかること
- Android Studio/KotlinでProduct Flavorの使い方
- Build Typeとは?
index
[open]
\ アプリをリリースしました /
環境
- Android Studio:Meerkat
- Kotlin:2.0.21
- AGP:8.9.2
- Gradle:8.11.1
- Android OS:15以降
アプリを環境で切り分けてビルドする
個人開発ではなかなかないですが、チーム開発となるとバックエンドの環境も開発(Develop)やステージング、本番環境などに切り分けられることが多いです。アプリ側もそれに準ずる形でエンドポイントへの向き先やアプリ名、AppIDなどを柔軟に切り替えて開発できる体制にしておくとスイッチコストを削減でき、効率的な開発を行うことが可能になります。
Android Studio(Android Gradle Plugin)にも環境を切り分けるための機構として「Product Flavor」と「Build Type」が導入されています。今回はこれらを使用してアプリ内の環境を切り分けを構築する方法をまとめて行きます。
Product FlavorとBuild Type
「Product Flavor」は開発版や本番において機能の差分を持たせたい場合に活用できる機能です。例えばdevelop、staging、productionといったバックエンドの環境に合わせたりする形で定義することが多いです。
「Build Type」はアプリをビルドする際の設定を切り替えたい場合に活用できる機能です。こちらはデフォルトでdebugとreleaseが用意されているのでそのまま使用すれば良いと思います。Build Type」自体の使い方は以下記事でも解説しているので参考にしてください。
buildTypes {
debug {
// com.example.app.debug (接尾辞に追加する)
applicationIdSuffix ".debug"
// デバッグビルドかどうか
debuggable true
}
release {
// リリースでコード圧縮するか
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
Build Variant
「Product Flavor」と「Build Type」で設定した値を元に「Build Variant」が生成されます。例えば「Product Flavor」がdevelop、staging、production「Build Type」がdebugとreleaseの場合は以下の通りになります。
- developDebug
- developRelease
- stagingDebug
- stagingRelease
- productionDebug
- productionRelease
フィルタリングする
自動生成される「Build Variant」ですが生成対象をフィルタリングすることも可能です。例えばproductionDebugのような使わなそうなものは以下のようにvariant.ignore = trueで無視するように設定すれば表示されなくなります。
android {
// 〜〜〜〜〜〜〜
variantFilter { variant ->
def flavorName = variant.flavors*.name?.join("")
def buildType = variant.buildType.name
if (flavorName == "production" && buildType == "debug") {
// 無効化する
variant.ignore = true
}
}
}
※ Gradle 8.x / AGP 8.x 以降ではvariantFilterは非推奨になりandroidComponents.beforeVariantsを使用することが推奨されるようになりました。そのため以下のように実装してください。
android {
// 〜〜〜〜〜〜〜
}
androidComponents {
beforeVariants(selector().all()) { variantBuilder ->
// dimension名を指定してFlavor名を取得
def flavorName = variantBuilder.productFlavors.get("env")
// buildTypeを取得
def buildType = variantBuilder.buildType
if (flavorName == "production" && buildType == "debug") {
// 無効化する
variantBuilder.enable = false
}
}
}
Product Flavorのセットアップ方法
「Product Flavor」を有効にするためには「build.gradle」に追加して行きます。例としてdevelop、staging、productionの3つを定義してみます。
android {
// フレーバー軸を定義
flavorDimensions "env"
// 複数の軸を定義することも可能
// flavorDimensions "tier", "env"
productFlavors {
develop {
dimension "env"
// applicationIdで明示的に指定することも可能
// applicationId "com.myApp.develop"
applicationIdSuffix ".develop"
versionNameSuffix "-dev"
buildConfigField "String", "API_BASE_URL", "\"https://dev.example.com/api\""
}
staging {
dimension "env"
applicationIdSuffix ".staging"
versionNameSuffix "-stg"
buildConfigField "String", "API_BASE_URL", "\"https://staging.example.com/api\""
}
production {
dimension "env"
// 本番は suffix なし
buildConfigField "String", "API_BASE_URL", "\"https://example.com/api\""
}
}
}
flavorDimensionsはフレーバーの軸となる値です。これは複数の軸も定義することができるのでアプリの要件に応じて増やしてあげてください。よくあるのは以下のような使い方です。
- env・・・develop, staging, production
- tier・・・free, paid
- region・・・japan, us, global
buildConfigFieldで色々な値を設定できるので詳細は以下の記事を参考にしてください。
リソースファイルの管理
「Product Flavor」を使用することでリソースをフレーバーごとに切り替えることができるようになります。以下のような形でsrcディレクトリ直下に各フレーバーごとのディレクトリが生成されその中でリソースファイルを管理することが可能です。これはフレーバーを切り替えると自動で該当のディレクトリ内のものが利用されるようになります。
src/
├── develop/
│ └── res/values/strings.xml
│ └── google-services.json ← Firebase用
├── staging/
│ └── res/values/strings.xml
│ └── google-services.json
├── production/
│ └── res/values/strings.xml
│ └── google-services.json
リソースファイルを追加する際はvaluesを右クリックして「New」>「Values Resource File」をクリックして「Source Set」の部分を変更すればOKです。mainを選択すると全てのフレーバーで共通のものを使用することが可能です。
アプリ名を変更する
アプリ名は「AndroidManifest.xml」からリソースファイルを参照して設定されています。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:label="@string/app_name"
>
// 〜〜〜〜〜〜〜〜〜〜
</application>
</manifest>
そのため各フレーバーに以下のようにそれぞれ設置してあげれば環境ごとにアプリ名も変更することができます。
<resources>
<string name="app_name">DevApp</string>
</resources>
<resources>
<string name="app_name">StgApp</string>
</resources>
コードから識別する
Kotlinのコード内からフレーバーを取得するにはBuildConfig.FLAVORを使用します。この中に実行されているフレーバー名が格納されているのでその値によって処理を分岐してあげればOKです。
if (BuildConfig.FLAVOR == "develop") {
// 開発用処理
}
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。






