ビルドバリアントでは、mainディレクトリに置いてあるファイルとの差分の内容を、ビルドバリアントのディレクトリに配置することで、そのビルドバリアントを選択してビルドした際に優先的に読み込まれるのかと思っていた。
結論から言うと、ビルドタイプの名称をもつディレクトリを作成し、mainディレクトリと構成の齟齬が無いように差分のファイルを配置することが必要です。
Androidのビルドバリアントをイチから理解する | フューチャー技術ブログ
これを踏まえて、soda
ビルドタイプとcola
ビルドタイプを作成してみた。
buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } debug { applicationIdSuffix ".debug" debuggable true } cola { applicationIdSuffix ".cola" debuggable true } soda { applicationIdSuffix ".soda" debuggable true } }
そして、次のようにmain/
ソースセットにGreeting.kt
を配置した。
package com.takagimeow.material3catalog.components class Greeting { fun greet() = "Main Greeting" }
ファイル階層は次の通り。
- src
- main
- java
- com.takagimeow.material3catalog
- components
- Greeting.kt
- components
- com.takagimeow.material3catalog
- java
- main
そして、soda
ビルドタイプ固有のファイルを作成するために次のディレクトリ階層を作成した。
- src
- soda
- java
- com.takagimeow.material3catalog
- components
- Greeting.kt
- components
- com.takagimeow.material3catalog
- java
- soda
Greeting.kt
の内容は次の通り。
package com.takagimeow.material3catalog.components import androidx.compose.material3.Text import androidx.compose.runtime.Composable class Greeting { fun greet() = "Soda Greeting" }
すると、次のようなRedeclaration: Greeting
エラーが発生した。
色々調べた結果、実装をビルドバリアント毎に変えたいクラスやコンポーザブルなどのリリース用の実装は、main/
ソースセットに配置するのではなく、新たにrelease
ビルドタイプ固有のファイルを作成する必要があることがわかった。
gradle - Error Redeclaration class configuring Android build variants - Stack Overflow
なので、main/
ソースセットに配置したGreeting.kt
は一旦削除する。そして、release
ビルドタイプ固有のファイルとしてGreeting.kt
を新たに作成する。
- src
- release
- java
- com.takagimeow.material3catalog
- components
- Greeting.kt
- components
- com.takagimeow.material3catalog
- java
- release
これにより、Redeclaration
エラーは解消される。
試しに、上記で定義したGreeting
クラスのgreet()
をMainActivity
で呼び出してみる。
class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) Log.d("MainActivity", "${Greeting().greet()}") setContent { Material3CatalogTheme { // A surface container using the 'background' color from the theme Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) { Greeting(stringResource(id = R.string.app_name)) } } } } }
[Build] -> [Select Build Variant]に移動して、ビルドバリアントをsodaに切り替えて実行してみると、soda
ビルドタイプで定義した内容が優先的に実行されるようになる。
実行した結果、LogcatにSoda Greeting
と表示されていることがわかる。
今度は、cola
ビルドバリアントに変更して実行してみることにする。
もちろんcola
ビルドタイプ固有のGreeting.kt
を作成していないので、Unresolved reference
エラーが発生する。
このように、ビルドバリアントごとに実装を切り替えたい場合はその実装をmain
ディレクトリには配置せずにrelease
ディレクトリを作成してその中に本番用の実装を定義するようにすることで、同じパッケージ名でファイルを作成したとしてもエラーを回避することができるようになる。