📚
KoinでAppモジュールのBuildConfigをサブモジュールに共有する
マルチモジュールでアプリを作る事が一般的になってきていますが、
ビルドタイプやProductFlavor毎に違った値を渡したい時にBuildConfigを使うことがあると思います。
しかし、AppモジュールのBuildConfigは他のモジュールから参照する事ができないためどうにか共有したい事があると思います。
今回はKoinを使った解決策を紹介したいと思います。
モジュールの構成
Appモジュール、Subモジュール、Utilモジュールの3つを用意しました。
参照関係は下図の通りで、Appが残りの両モジュールを参照し、SubモジュールがUtilモジュールだけを参照しており、Utilは参照されるだけとなっています。
Utilモジュールに共有用のDataクラスを用意
data class AppConfig(
val test: String
)
Appモジュールでfactoryの指定
private val module = org.koin.dsl.module {
factory { AppConfig(BuildConfig.test) }
}
Koinのmodule生成時にfactoryでBuildConfigの欲しい値をセットするように指定します。
Subモジュールでinject
class BuildConfigTest: KoinComponent {
private val appConfig: AppConfig by inject()
fun getConfig(): String = appConfig.test
}
動作確認
AppモジュールのAcitivityから呼び出してログ出力してみます。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
println("Config: ${BuildConfigTest().getConfig()}")
}
}
無事にサブモジュールにもBuildConfigの値を渡す事ができました。
I/System.out: Config: TEST-D
ハマりポイント
新規のプロジェクトであれば上記の方法で問題なく動作するはずです。
が、過去に同じモジュール名のモジュールを作成して削除した事がある場合、
NoSuchFieldError
で怒られるようです。
こちらは細かい情報を追いかけていませんが、もしNoSuchFieldError
でBuildConfigの値が読めない場合にはモジュール名を変更すると解決するかもしれません
※今回の例ではSubモジュールの名前を変更する(BuildConfigの値を受け取るモジュールの名前)
サンプルソースコード
Discussion