Android のモジュールのパスを簡潔にする


はじめに

Android Studio1 上で multi-module project2 を構成する際に、モジュール名とフォルダ構成に関して、以下のようなトレードオフを考えることがあります。

  • フォルダ構成の混沌さを許容しつつ、モジュール名を簡潔する。
  • 中間フォルダを設けてフォルダ構成をわかりやすくしつつ、モジュール名に中間フォルダ名を含める。

本稿では、これらのトレードオフの説明と、双方のメリットのみを享受する方法を示します。

トレードオフ

◆ サブモジュール名を簡潔にする

サブモジュール名を :android, :kotlin のように簡潔に記述する。

☆ メリット

サブモジュール名が簡潔になります。

include ':android'
include ':kotlin'

☆ デメリット

フォルダ構成がカオスになり、サブモジュールの名前空間も制限されます。3

モジュール非モジュールフォルダ数十個が混然一体とした状況を想像してみてください。カオスです、、、。

◆ 中間フォルダを設ける

☆ メリット

フォルダ構成が簡潔になり、サブモジュールの名前空間も制限されません。4

☆ デメリット

サブモジュール名が無駄に長くなります。

include ':modules:android'
include ':modules:kotlin'

メリットのみを享受する方法

◆ settings.gradle

settings.gradle
include(
        ':android',
        ':kotlin'
)
// ↑ は以下と等価です。どちらでもOKです。
// include ':android'
// include ':kotlin'

project(":android").projectDir = new File(rootDir, "/modules/android")
project(":kotlin").projectDir = new File(rootDir, "/modules/kotlin")

☆ 自動化版

modules フォルダ直下に全サブモジュールのみが配置されるのであれば、以下のようにモジュールの列挙から設定までを自動化することもできます。5

settings.gradle
new File("modules").listFiles().each { file ->
    def name = file.getName()
    def path = ":$name"
    include path
    project(path).projectDir = new File(rootDir, "/modules/$name")
}

◆ サブモジュールの参照例

include ':android'
include ':kotlin'

◆ Android 用の表示例

おわりに

  • Android Studio 上で multi-module project を構成する際に、Gradle project に任意の名称を設定することにより、モジュール名とフォルダ構成の両方を簡潔にする方法を説明しました。
  • settings.gradle の記述を自動化する例を示しました。

それでは、また。

追記(2020-08-04)

モジュールを動的に追加する Gradle Plugin を作ってみた

概要

  • "build.gradle" もしくは "build.gradle.kts" の存在する箇所をすべて include します。ただし、root project, buildSrc は無視します。
  • 例えば、"/modules/android/build.gradle.kts" が存在する場合は、":modules:android" が include されます。

使い方

settings.gradle.kts もしくは settings.gradle に以下のように設定します。

注意: build.gradle ではなく settings.gradle なので注意!

settings.gradle.kts
buildscript {
    repositories {
        // mavenLocal() // for of-commons SNAPSHOT release
        maven { url = uri("https://beyondseeker.github.io/of-commons/mvn-repo") } // for of-commons
        google()
        jcenter()
    }
    dependencies {
        classpath("com.objectfanatics:gradle-plugin-dynamicmodulesplugin:0.0.1")
    }
}

apply(mapOf("plugin" to "com.objectfanatics.gradle.plugin.dynamicmodulesplugin"))
settings.gradle
buildscript {
    repositories {
        // mavenLocal() // for of-commons SNAPSHOT release
        maven { url = uri("https://beyondseeker.github.io/of-commons/mvn-repo") } // for of-commons
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.objectfanatics:gradle-plugin-dynamicmodulesplugin:0.0.1'
    }
}

apply plugin: 'com.objectfanatics.gradle.plugin.dynamicmodulesplugin'

  1. InteliJ Idea でも同様だと思われます。 

  2. Gradle 的には Multi project. 

  3. ルートフォルダ直下のモジュールが増えるほど、ルートフォルダ直下の名前空間が圧迫されてしまう。 

  4. 中間フォルダの直下にはモジュール用のフォルダしか配置されないので、名前空間を100%利用できます。 

  5. モジュール名の増減や変更時に settings.gradle を変更する必要がないのでラクチンです。