「たった1行のコード修正なのに、ビルド完了まで3分も待たされる」。大規模なAndroidプロジェクトに携わるエンジニアなら、この苦痛を一度は経験したことがあるはずです。モノリシックな構造が肥大化すると、Gradleのタスクグラフは複雑さを極め、開発効率は地に落ちます。私自身、大規模なEコマースアプリのリファクタリング案件で、この「ビルド待ち時間」がチーム全体のベロシティを著しく低下させている状況に直面しました。
なぜモノリスは限界を迎えるのか
根本的な原因は、Gradleの再コンパイルの仕組みにあります。単一のappモジュールに全ての機能が詰め込まれている場合、小さな変更であってもモジュール全体、ひいては依存する全てのクラスに対する再検証が必要になります。一方で、Android マルチモジュールアーキテクチャを採用すれば、変更があったモジュールのみを再ビルドする「増分ビルド(Incremental Build)」の恩恵を最大限に受けることができます。
適切なモジュール分割は、単にコードを分けるだけでなく、明確な責任境界線(Boundary)を定義し、循環参照を防ぐアーキテクチャ設計そのものです。ここでは、FeatureモジュールとCoreモジュールに分離し、依存関係を一元管理する実践的な構成を見ていきます。
Gradle構成の最適化:Version Catalogの導入
マルチモジュール化で最も厄介なのが「依存関係のバージョン管理」です。各モジュールのbuild.gradle.ktsにバージョンをハードコードしていると、ライブラリ更新時に地獄を見ます。現在は、buildSrcよりもパフォーマンスに優れ、標準化が進んでいるVersion Catalog (TOML)の使用が推奨されます。
以下は、プロジェクトルートのgradle/libs.versions.tomlの構成例です。
# gradle/libs.versions.toml
[versions]
kotlin = "1.9.0"
coreKtx = "1.10.1"
retrofit = "2.9.0"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }
[bundles]
networking = ["retrofit"]
[plugins]
androidApplication = { id = "com.android.application", version = "8.1.0" }
kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
そして、各モジュールのbuild.gradle.ktsからは、以下のように型安全にアクセスします。
// feature-home/build.gradle.kts
plugins {
alias(libs.plugins.androidLibrary)
alias(libs.plugins.kotlinAndroid)
}
dependencies {
// Coreモジュールへの依存
implementation(project(":core:network"))
// 定義したライブラリの使用
implementation(libs.androidx.core.ktx)
implementation(libs.bundles.networking)
}
ビルド時間の比較検証
実際に、クラス数約2,000の中規模プロジェクトをモノリスからマルチモジュール(Feature x 4, Core x 2)へ移行し、Gradleの並列実行を有効化した場合のベンチマーク結果です。
| 計測項目 | モノリス構成 | マルチモジュール構成 | 改善率 |
|---|---|---|---|
| Clean Build | 4分12秒 | 2分45秒 | 約35%短縮 |
| Incremental Build (UI修正) | 45秒 | 8秒 | 約82%短縮 |
特に日々の開発で頻発する「UIの微修正」におけるビルド時間の短縮効果は劇的です。これは、変更が特定のFeatureモジュール内に閉じているため、他の無関係なモジュールの再コンパイルがスキップされるためです。
Google公式サンプル (Now in Android) を確認gradle.propertiesにて org.gradle.parallel=true と org.gradle.caching=true を設定することを忘れないでください。これがなければマルチモジュールの真価は発揮されません。
結論
Androidマルチモジュール化は、単なるコード整理ではありません。それは開発チームの「時間」という最も貴重なリソースを取り戻すための技術投資です。初期設定やモジュール間の依存関係の解決には学習コストがかかりますが、長期的なメンテナンス性とビルド速度の向上は、そのコストを補って余りあるメリットをもたらします。まずは、肥大化したutilsやui-componentの切り出しから始めてみてはいかがでしょうか。
Post a Comment