マルチモジュール構成のAndroidプロジェクトでbuild.gradleの記述を共通化する

モジュール毎のbuild.gradleのdependenciesの記述を共通化したい

Android Studioでレイヤー毎にモジュール化を行ったプロジェクトを作成した際に、モジュール間の依存性解決にKoinを用いたところ、各モジュールのdependenciesにそれぞれKoinに対するimplementationを記載しなければいけなくなった。

dependencies {
    // Koin
    implementation "org.koin:koin-core:$rootProject.koin_version"
    implementation "org.koin:koin-android:$rootProject.koin_version"
}

これはウザい。 なにか良い方法が無いかなと調べたところ、プロジェクトレベルのbuild.gradleにsubprojectsブロックを定義するとすべてのモジュールで共通となる記述をまとめることが出来るようなので、試してみました。

ところがimplementationが定義されていないよ的なエラーがでてGradle Syncが失敗する…

原因調べたところ、appモジュールやライブラリモジュール作成時に定義されている

apply plugin: 'com.android.application'

などの後に定義する必要があるようです。たしかにそうですね。

解決方法

上記のapply pluginの部分をsubprojectsに移動したのですが、1つ困った事があり、

モジュールのタイプ プラグイン
App Moduleの場合 com.android.application
Android Library Moduleの場合 com.android.library

みたいな感じでプラグイン名を変える必要があったのでモジュール名によって判定するコードを追加した。

subprojects {
    switch (project.name) {
        case 'app':
            apply plugin: 'com.android.application'
            break
        default:
            apply plugin: 'com.android.library'
    }

    dependencies {
        // Koin
        implementation "org.koin:koin-core:$rootProject.koin_version"
        implementation "org.koin:koin-android:$rootProject.koin_version"
    }
}

Java LibraryやDynamic Feature Module等を使用している場合はまた別のプラグインとなるので、モジュール名によって判定するか、モジュール名の命名規則を決めてswitch文で正規表現を用いた判定などを行う必要がある。

最初のswitch文だけ書いておけば、通常のモジュール側のbuild.gradleと同じ機能がほぼ使えるので、 androidブロックの内容などもsubprojectsで共通化する事が出来るのでapp, library側含めてかなりスッキリさせる事が出来そう。