flavorDimensionsによるflavorの指定方法


※ `flavorDimension`指定は2015/10/27現在のAndroidStudioでdeprecatedになっていたため、記述を修正しました。


例えば、[こちら](http://qiita.com/boohbah/items/b9ea5e0aaff5b955d0ef)で紹介しているように、productFlavorによってビルド設定を変えたいような場面があると思います。

```
android {
    productFlavors {
        // 開発環境
        dev {
            // 開発時にはビルドを高速化！
            minSdkVersion 21
        }
        // プロダクション環境
        prod {
            minSdkVersion 14
        }
    }
}
```

しかし、すでにproductFlavorによって複数のソースツリーが管理されている場合、productFlavorによる設定を変えることは難しいです。

```
android {
    productFlavors {
        // 課金なしのアプリ
        freeApp {
			...
        }
        // 課金ありアプリ
        paidApp {
           ...
        }
    }
}
```

なぜなら、これらのflavorをにはたいてい対応したソースツリーが存在するからです。

```ツリー構成はこんな感じになっている
src/main/java
src/freeApp/java
src/freeApp/rsc
src/paidApp/java
src/paidApp/rsc

```

これに無理やりビルド設定のflavorをかけ合わせると

```
android {
    productFlavors {
        // 課金なしのアプリの開発版
        freeAppDev {
           minSdkVersion 21
			...
        }
        // 課金なしのアプリのプロダクション版
        freeAppProd {
           minSdkVersion 15
			...
        }
        // 課金ありアプリの開発版
        paidAppDev {
            minSdkVersion 21
           ...
        }
        // 課金ありアプリのプロダクション版
        paidAppProd {
           minSdkVersion 15
           ...
        }
    }
}
```

となり対応するソースツリーは

```ツリー構成はこんな感じになってしまう
src/main/java
src/freeAppDev/java -- freeAppDevとfreeAppProdは同じソースが入っている必要がある
src/freeAppDev/rsc
src/freeAppProd/java
src/freeAppProd/rsc
src/paidAppDev/java -- paidAppDevとpaidAppProdは同じソースが入っている必要がある
src/paidAppDev/rsc
src/paidAppProd/java
src/paidAppProd/rsc

```

のようになってしまい、2重管理が必要になります。


# そこでflavorDimensionsだよ

Android Studioには`flavorDimensions`という機能があり、`flavorDimensions`指定を行うと個々のflavorに対して、直交する次元(dimension)をもたせ、それを組み合わせたbuild variantを作ることができます。

何を言っているかよくわからないと思いますが実際に上記の例に`flavorDimensions`を適用してみましょう

```
    flavorDimensions "sourceSet", "usage"

    productFlavors {
        free {
            dimension "sourceSet"
            // 従来のflavorの設定を記述
        }

        paid {
            dimension "sourceSet"
            // 従来のflavorの設定を記述
        }

        product {
            dimension "usage"
            minSdkVersion 15
        }

        dev {
            dimension "usage"
            // minSdkVersionを21に設定するとmultidexでのビルドが速くなる
            minSdkVersion 21
        }
    }

    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.txt'
        }
        debug {
            jniDebuggable true
            minifyEnabled false
            shrinkResources false
        }

    }




```

ここでは`sourceSet`と`usage`という2つのdimensionを定義しており、それぞれ`free`と`paid`のflavorDimensionは`sourceSet`、また`product`と`dev`のflavorDimensionは`usage`を割り当てています。この場合flavorは`sourceSet`と`usage`の組み合わせて

- freeProduct
- freeDev
- paidProduct
- paidDev

の4つと定義されます。
また、`release`/`debug`のbuildTypeと組み合わせると

- `freeProductRelease`
- `freeProductDebug`
- `freeDevRelease`
- `freeDevDebug`
- `paidProductRelease`
- `paidProductDebug`
- `paidDevRelease`
- `paidDevDebug`

の8種類のbuild variantが生成されます。

便利！

# flavorをJavaのコードから参照する場合

従来のflavorはJavaのコード上から以下のように参照できました。

```java
        switch (BuildConfig.FLAVOR) {
            case "paid":
                // paid flavorの時の処理
                break;
            case "free":
                // free flavorの時の処理
                break;
        }
```


上記のようにdimensionsを定義すると`BuildConfig.FLAVOR`以下のように参照できます。

```java
        switch (BuildConfig.FLAVOR) {
            case "paidProduct":
            case "paidDev":
                // paid flavorの時の処理
                break;
            case "freeProduct":
            case "freeDev":
                // free flavorの時の処理
                break;
        }
```

ただ、この場合新しくdimensionが増えると分岐の数が増え、そのたびにこのコードを修正しなければならなくなります。
そういうときは以下のような指定を使います。

```java
        switch (BuildConfig.FLAVOR_sourceSet) {
            case "paid":
                // paid flavorの時の処理
                break;
            case "free":
                // free flavorの時の処理
                break;
        }
```

なんとdimensionごとにBuildConfig上に定数が生成されるんです。これでかりにdimensionが増えても注目すべきdimensionのFlavorだけ取り出して処理の分岐を扱うことができます。

めでたしめでたし