避免多模块 Android 中的 Gradle 重复

2021-09-03 10:03:09 浏览数 (2382)

当你有一个包含许多模块的 Android 项目时,你可能会发现在各个模块中的 build.gradle 文件中复制了很多 gradle 配置(通常通过复制和粘贴)。

我在互联网上阅读了各种尝试避免这种情况的方法,直到看到了这篇博客文章。这篇文章使用模块的名称来确定要应用哪些 gradle 插件以及要用于该模块的配置。

在我的多个模块项目之一中,我使用过类似的东西。然而,不同之处在于我在每个单独的模块 build.gradle 中应用了所需的插件,在根 ​build.config​ 中,我同时使用模块名称和它的属性来添加适当的共享配置。

例如,这里是根 ​build.gradle​ 中所有模块的公共共享配置:

subprojects {
    afterEvaluate { project ->
        if (project.hasProperty("android")) {
            android {
                compileSdkVersion 30
                buildToolsVersion '30.0.2'
                defaultConfig {
                    minSdkVersion 23
                    targetSdkVersion 30
                }
                compileOptions {
                    sourceCompatibility JavaVersion.VERSION_11
                    targetCompatibility JavaVersion.VERSION_11
                }
            }
        }
}

这个应用程序是一个混合的 Java 和 Kotlin 项目,所以只有一些模块使用 Kotlin。在 Kotlin 模块中,我应用了 kotlin 插件。

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

然后在根 ​build.gradle​ 中,我可以将 Kotlin 配置添加到这些模块中:

if (project.hasProperty('kotlin')) {
        android {
            kotlinOptions {
                jvmTarget = JavaVersion.VERSION_11.toString()
            }
        }
        dependencies {
            implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
            implementation 'androidx.core:core-ktx'
        }
}

如果有仅适用于某些模块的通用配置,我也可以使用模块名称作为过滤器,只为这些模块添加该配置。例如对于除 app 模块之外的所有模块:

if (project.hasProperty('android') && !name.equalsIgnoreCase('app')) {
      ...
}

同样对于具有特定名称的模块:

if (project.hasProperty('android') && name.equalsIgnoreCase('feature-1')) {
      ...
}

请注意,我使用根 ​build.gradle​ 来包含通用配置以保持简单,但也有更复杂的方法,可以使用 ​buildSrc ​目录代替。

感谢各位的阅读!