📑

[Android]MVVM+MultiModule Gradleセットアップ

2023/12/13に公開

セットアップを始めよう

Android開発において、Google公式推奨のクリーンアーキテクチャベースにMVVM+MulitiModuleの設定を行なっていこうと思います。
※クリーンアーキテクチャ推奨理由については下記別途記載

Android開発におけるビルド設定については、Gradleを使って行なっていきます。

Gradleファイルとは

ビルド自動化ツールで、Javaバイトコードに変換し、メモリ上に配置してJVM上で実行するための記述ファイル

Groovy KotlinDSL(KTS) で記述される
KotlinDSL(KTS)が推奨されているが、すべてのプラグインやライブラリがKotlin DSLに完全に対応しているわけではないため、移行には注意が必要
https://developer.android.com/studio/build/migrate-to-kts?hl=ja

ビルドの仕組み

リソースとソースコードをコンパイルしてAPKと呼ばれるパッケージを作成

※以下の図は公式ドキュメントからの引用

Gradleの3つのフェーズ

Gradleファイルは3つのフェーズによって構成されます。

1.初期化フェーズ (init.gradleまたはinit.gradle.kts): このフェーズでは、Gradleの初期化スクリプトが実行されます。このスクリプトは、ビルド全体の環境設定やプロジェクト間で共有される設定を定義します。init.gradleまたはinit.gradle.ktsは、Gradleビルドプロセスの最初に読み込まれ、実行されます。

2.設定フェーズ (settings.gradleまたはsettings.gradle.kts): 初期化フェーズの後、設定フェーズが開始され、settings.gradleまたはsettings.gradle.ktsが読み込まれ、実行されます。このスクリプトは、プロジェクトの構造を設定し(例えば、サブプロジェクトのインクルードなど)、Gradleプロジェクトの全体的な設定を行います。

3.実行フェーズ (build.gradleまたはbuild.gradle.kts): 設定フェーズの後、実行フェーズが始まり、各プロジェクト(ルートプロジェクトとサブプロジェクト)のbuild.gradleまたはbuild.gradle.ktsスクリプトが読み込まれ、実行されます。これにより、プロジェクトのビルドロジックやタスクが処理されます。

例)
ルートプロジェクトのsetting.gradle.kts
(サブディレクトリのサブプロジェクトへの設定)

サブディレクトリのsetting.gradle.ktsを含める場合
// ルートプロジェクトの settings.gradle で別のプロジェクトを含める例
includeBuild '../another-project'

ルートプロジェクトのbuild.gradle
プロジェクト全体に適用される依存関係、プラグインの適用、ビルドスクリプトで定義されたタスクの設定などが含まれます。
ルートプロジェクトのbuild.gradleが実行された後、Gradleはサブプロジェクトのbuild.gradleファイルを順に実行し、それぞれのサブプロジェクトのビルド設定を適用します。

※.gitmodules設定については下記別途記載

サブモジュールをリポジトリに追加する際に自動的に作成されます
(手動の場合
git add .gitmodules
git commit -m "Add example-lib submodule at libs/example-lib")

コマンド
git submodule add https://url.to/submodule/repository.git path/to/submodule

.gitmodules ファイルの例

[submodule "LibraryOne"]
path = externals/libraryone
url = https://github.com/exampleuser/libraryone.git

[submodule "LibraryTwo"]
path = externals/librarytwo
url = https://github.com/exampleuser/librarytwo.git

※gradlew.batはWindows環境用のGradle Wrapperバッチファイルです。
詳細については下記別途記載

2種類のプロジェクト設定

Android開発におけるビルド設定は大きく分けて2種類存在します

  • プロジェクトレベル
    プロジェクト配下の全てのモジュールに適用される、アプリのビルドに必要なリポジトリや依存関係を定義
  • モジュールレベル
    モジュールレベルでは、build.gradleの所属するモジュールに適用される依存関係や、カスタムビルドの設定
    (さらにこちらを複数モジュールにプロジェクトを分割するマルチモジュール化ができる)

※プロジェクトとモジュールの関係と、それぞれのbuild.gradleファイルの位置を示す図

MyProject (プロジェクトのルートフォルダ)
├── build.gradle (プロジェクトレベルのビルド設定)
├── settings.gradle (モジュール設定)
├── app (モジュール1のフォルダ)
│   ├── build.gradle (モジュール1のビルド設定)
│   └── ... (その他のファイルやフォルダ)
├── library (モジュール2のフォルダ)
│   ├── build.gradle (モジュール2のビルド設定)
│   └── ... (その他のファイルやフォルダ)
└── ... (その他のファイルやフォルダ)

プロジェクトレベルの設定

アプリのバージョン設定

class Version {
    static final code = 1
    static final name = "1"
}

ビルドに必要なライブラリや、kotlin、Firebaseなどの依存関係をPlugin

plugins {
    id 'com.android.application' version '8.0.1' apply false
    id 'com.android.library' version '8.0.1' apply false
    id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
}

プロダクト フレーバーの設定

 if (subProject.hasProperty('android')) {
            try {
                android {
                    flavorDimensions "environment"
                    productFlavors {
                        create("dev") {}
                        create("stg") {}
                        create("prod") {}
                    }
                }

サブプロジェクト毎に統一して行いたい依存関係の設定

switch (projectName) {
                    case ":app":		   		

コンパイルバージョン ターゲットバージョンの設定

android {
                def version = new Version()
                compileSdkVersion 34
                defaultConfig {
                    versionCode = version.code
                    versionName = version.name
                    targetSdkVersion 34

compileSdkVersionは、アプリをコンパイルする際に使用されるAndroid SDKのバージョンのAPIに対してアプリケーションがコンパイルされるがこの設定は実行時の挙動には直接影響しません。
targetSdkVersionは、アプリが最適化されるべきAndroidのターゲットバージョンで、どのAndroidバージョンに対して最適化されているかをシステムに伝えシステムは互換性モードなどの特定の動作をアプリに適用するかどうかを決定する。

アプリモジュールの設定

ビルドタイプの設定や署名設定などを主に行う

署名設定とは

GooglePlayStoreにてアプリを公開する際、以下の2つの鍵を使って行う必要があります。
アプリ署名鍵 → Googleがユーザーに配布するときの行う署名鍵 APKに対して署名
アップロード鍵 → 開発者がGoogleにデプロイするときにGoogleが確認する鍵
Gradleのsigningメソッドに鍵情報を記載

fun signing(
 val fileName = ~~~.plus("/app/keystore.jks")
storeFile = File(fileName)
 storePassword =
  keyPassword = 
  keyAlias =

鍵を格納するファイルパスを記載
格納ファイルの記載
アップロード鍵のパスワード環境変数記載
アプリ署名鍵のパスワード環境変数記載
アプリ署名鍵の環境変数を記載
※環境変数はlocal.propertiesか、CIツール上に保管しビルドスクリプト内に直接機密情報を記述することなく、必要な情報を安全に参照できるようにしましょう。

サブモジュールの設定

サブモジュールのレイヤー毎に依存関係を定義
アーキテクチャの方針に従って、依存関係が逆流することがないように注意しながら、依存関係を定義する必要があります。

クリーンアーキテクチャ推奨理由

※クリーンアーキテクチャの推奨理由
1.外部の変更から保護
2.システムのビジネスルールのカプセル化
3.アプリケーション固有のビジネスルールのカプセル化
4.保守性の向上
5.テストのしやすさ
クリーンアーキテクチャの各役割

エンティティ (Entities): システムのビジネスルールをカプセル化します。
ユースケース (Use Cases): アプリケーション固有のビジネスルールを含みます。
インターフェースアダプター (Interface Adapters): ユーザーインターフェース、外部API、データベースなどの外部との通信を担います。
フレームワークとドライバー (Frameworks and Drivers): 具体的な技術的詳細、フレームワーク、ツールなどが含まれます

gradlew.batにてWindowsでの環境設定

Gradle Wrapperは、プロジェクトに同梱されるスクリプトとJarファイルのセットで、プロジェクトのビルドに必要な正確なGradleバージョンを自動的にダウンロードして使用するためのものです。これにより、開発者やビルドシステムが事前にGradleをインストールしていなくても、プロジェクトをビルドできるようになります。
バージョンの一貫性: プロジェクトがどのGradleバージョンでビルドされるべきかを指定し、開発者間やCI/CD環境でのバージョンの一貫性を保証します。
環境のセットアップの簡素化: 新しい開発者がプロジェクトに参加する際、Gradleのインストールを心配する必要がなく、プロジェクトのビルドをすぐに開始できます。
バージョンアップの容易さ: Gradleの新しいバージョンにアップグレードする場合、gradle-wrapper.propertiesファイル内のバージョン番号を変更するだけで済みます

使用方法
Windows環境でgradlew.batを使用するには、コマンドプロンプトやPowerShellからプロジェクトディレクトリに移動し、次のように入力します。
.\gradlew.bat <task>
ここで<task>は実行したいGradleタスクです(例: build, clean, testなど)。
Linux, macOS, またはその他のUnix系OSでは、代わりにgradlewスクリプト(拡張子なし)を使用します
./gradlew <task>
これらのスクリプトを使用することで、プロジェクト固有のGradleバージョンを使用してタスクを実行することができます。プロジェクトディレクトリにgradlewやgradlew.bat、およびgradle/wrapper/gradle-wrapper.jarとgradle/wrapper/gradle-wrapper.propertiesファイルが含まれていることを確認してください。これらはGradle Wrapperの構成ファイルと実行可能ファイルです。

https://docs.gradle.org/current/userguide/userguide.html
https://future-architect.github.io/articles/20210120/

Discussion