如何避免Gradle在多模块Android中的重复工作

393 阅读1分钟

避免Gradle在多模块Android中的重复工作

当你有一个有很多模块的Android项目时,你可能会发现很多gradle配置在不同模块的build.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目录代替。