Android Gradleプラグインにおけるビルドタイプ・フレーバー・フレーバーグループ
Android Gradleプラグインには、「同じような機能を持つけれども少しだけ異なるアプリ」を、便利に開発するための機能が備わっています。
そのためには以下の3つの概念を理解しておく必要があるのですが、すぐに分からなくなってしまうので、ここにメモしておこうと思います。
- ビルドタイプ
- フレーバー
- フレーバーグループ
ビルドタイプ
ビルドタイプは「デバッグ版」「リリース版」を分けるのに使います。デフォルトでは、デバッグ版を表すdebug
と、リリース版を表すrelease
の2つのタイプが定義されています。
デバッグ版にはデバッグ署名が付けられ、リリース版には、build.gradle
に書いた設定にしたがって、リリース向けの署名が付けられる、といった具合です。
もちろん、必要であれば第3のビルドタイプ、第4のビルドタイプを定義することもできますし、ビルドタイプごとに、ソースコードを差し替えたり、リソースを差し替えたりすることもできます。
なお、デフォルトでは、テストは「デバッグ版」に対してしか実行されません。試験対象を他のビルドタイプに変更することはできますが、複数のビルドタイプを試験対象にすることはできません*1。
フレーバー
フレーバーは、アプリケーションの一部の機能や振舞いをカスタマイズするために使います。たとえば「広告あり」フレーバーと「広告なし」フレーバーを定義する、といった具合です。
フレーバーは、build.gradle
に定義することではじめて作られますが、1つもフレーバーが定義されていない場合は、暗黙的に名前のない1つのフレーバーが定義されているとみなされます。
ビルドタイプと同様に、フレーバーについても、それぞれソースコードを差し替えたり、リソースを差し替えたりすることができます。
こちらは、ビルドタイプとは異なり、全てのフレーバーが試験対象となります。そのため、テストコードもフレーバーごとに差し替えることが可能になっています。
フレーバーグループ
フレーバーが複数定義されている場合、gradle assemble
コマンドによってビルドされるapkは、ビルドタイプの集合とフレーバーの集合の全組み合わせになります。
たとえば、ビルドタイプとフレーバーが、それぞれ以下のように定義されているとします。
- ビルドタイプ:
debug
,release
- フレーバー:
f1
,f2
,fa
,fb
この場合にビルドされるapkは、以下の8種類になります。
- ビルドタイプが
debug
で、かつ、フレーバーがf1
のもの - ビルドタイプが
debug
で、かつ、フレーバーがf2
のもの - ビルドタイプが
debug
で、かつ、フレーバーがfa
のもの - ビルドタイプが
debug
で、かつ、フレーバーがfb
のもの - ビルドタイプが
release
で、かつ、フレーバーがf1
のもの - ビルドタイプが
release
で、かつ、フレーバーがf2
のもの - ビルドタイプが
release
で、かつ、フレーバーがfa
のもの - ビルドタイプが
release
で、かつ、フレーバーがfb
のもの
フレーバーグループは、上記のようなapk生成時の組み合わせを制御するためのもので、フレーバーを複数のグループに分割するために利用します。たとえば、この4つのフレーバーを、以下のように2つのフレーバーグループに所属させてみます。
- フレーバーグループ1:
f1
,f2
- フレーバーグループ2:
fa
,fb
このようにグループ分けを行うと、ビルドされるapkは、ビルドタイプの集合と、各フレーバーグループの集合の全組み合わせとなります。この場合だと{build
, release
} × {f1
, f2
} × {fa
, fb
}という組み合わせになりますので、以下の8種類のapkがビルドされることになります。
- ビルドタイプが
debug
で、かつ、フレーバーがf1
、かつfa
のもの - ビルドタイプが
debug
で、かつ、フレーバーがf1
、かつfb
のもの - ビルドタイプが
debug
で、かつ、フレーバーがf2
、かつfa
のもの - ビルドタイプが
debug
で、かつ、フレーバーがf2
、かつfb
のもの - ビルドタイプが
release
で、かつ、フレーバーがf1
、かつfa
のもの - ビルドタイプが
release
で、かつ、フレーバーがf1
、かつfb
のもの - ビルドタイプが
release
で、かつ、フレーバーがf2
、かつfa
のもの - ビルドタイプが
release
で、かつ、フレーバーがf2
、かつfb
のもの
このように、フレーバーグループを適切に使うことで、いくつもの差分を積み重ねたapkを一気にビルド・テストすることができるようになります。
優先順位
これらの機能を駆使して、差分を積み重ねたapkがビルドできるようになると、各差分に同一の定義がある場合(たとえば同じ名前のstringリソースが、debug
とf1
とfa
に定義されている場合など)に、何が優先されるのか、ということが問題になります。
それもきちんと決まっていて、以下のリストのうち、上にある方がより優先度が高いことになっています。言い換えると、リストの下から順に上書きされていきます。
- ビルドタイプ
- フレーバーグループのうち、1つめに宣言したもの
- フレーバーグループのうち、2つめに宣言したもの
- ...
このように、フレーバーグループの宣言順序によって優先度が決まってしまうので、フレーバーグループの宣言には気を使う必要がありあます。なお、フレーバーグループの宣言は、以下のような感じで行います。
android { ... // "group1"の方が"group2"より優先度が高い flavorGroups "group1", "group2" ... }
まとめ
特に分かりにくいと思われる点をざっくりまとめてみます。
- ビルドタイプもフレーバーも、ソースコードやリソースの一部を差し替えることが出来る、という点では同じですが、ビルドタイプは1つしかテスト対象にできない点に注意が必要です。
- ビルドされるapkは、ビルドタイプとフレーバーの組み合わせになりますが、フレーバーグループを定義することで、組み合わせ方法を制御することができます。
- フレーバーグループの宣言順序によって、差分適用の優先度が変化することに注意が必要です。
*1:adt-devのやりとりによると、近い将来にこの制限は撤廃されそうな雰囲気です。