在多模块项目中优化重复gradle配置

Android面试技术要点汇总
2021-05-17 14:29 · 阅读时长7分钟
小课

随着项目的模块的增加,项目中的gradle配置文件也越来越多,但是这些配置中有很多项其实是相同的,比如说一些sdk相关的版本、lint的配置、packaging的配置等等。重复配置不仅浪费时间,而且在改动时容易出错,下面介绍一种为所有项目统一配置相同参数的方法,减少项目中重复的gradle配置,这个和之前在《Gradle buildSrc替换方案之Composing builds》提到的方式不一样,这种方式在使用buildSrc的同时,能让gradle配置更加简洁。

主要是通过在项目根目录的build.gradle.kts中为所有子项目填充默认配置,主要配置如下:

subprojects {
    project.plugins.applyBaseConfig(project)
}

这个applyBaseConfig()方法是我们自定义的扩展方法,用于筛选App模块和Library模块。

1fun PluginContainer.applyBaseConfig(project: Project) {
2    whenPluginAdded {
3        when (this) {
4            is AppPlugin -> {
5                project.extensions
6                    .getByType<AppExtension>()
7                    .apply {
8                        baseConfig()
9                    }
10            }
11            is LibraryPlugin -> {
12                project.extensions
13                    .getByType<LibraryExtension>()
14                    .apply {
15                        baseConfig()
16                    }
17            }
18        }
19    }
20}

如果是App模块Library模块则执行baseConfig()方法,这个方法就是给模块填充的默认配置,根据项目需求自定义。

1fun BaseExtension.baseConfig() {
2    compileSdkVersion(Versions.compileSdkVersion)
3
4    defaultConfig {
5        minSdkVersion(Versions.minSdkVersion)
6        targetSdkVersion(Versions.targetSdkVersion)
7        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
8    }
9
10    compileOptions {
11        sourceCompatibility = JavaVersion.VERSION_11
12        targetCompatibility = JavaVersion.VERSION_11
13    }
14
15    tasks.withType<KotlinCompile> {
16        kotlinOptions {
17            jvmTarget = JavaVersion.VERSION_11.toString()
18        }
19    }
20
21    compileOptions {
22        sourceCompatibility = JavaVersion.VERSION_1_8
23        targetCompatibility = JavaVersion.VERSION_1_8
24    }
25
26    lintOptions {
27        isWarningsAsErrors = true
28        isAbortOnError = true
29    }
30
31    buildTypes {
32        getByName("release") {
33            isMinifyEnabled = false
34            proguardFiles(
35                getDefaultProguardFile("proguard-android-optimize.txt"),
36                "proguard-rules.pro"
37            )
38        }
39    }
40}

下面是完整的示例项目,示例中使用了buildSrc的方式来统一定义一些通用的常量,如果对这部分感兴趣,可以查看之前的课程《Gradle buildSrc替换方案之Composing builds》

文件大小修改时间
app
2022年03月24日
build
2022年03月24日
build.gradle.kts
2 kB 2022年03月24日
buildSrc
2022年03月24日
gradle/wrapper
2022年03月24日
gradle.properties
1 kB 2022年03月24日
gradlew
6 kB 2022年03月24日
gradlew.bat
3 kB 2022年03月24日
library
2022年03月24日
local.properties
437 B 2022年03月24日
settings.gradle.kts
28 B 2022年03月24日

很多项目由于历史原因,可能无法使用kotlin-script的方式来配置gradle,下面贴出一份使用groovy配置的示例。

1/**
2 * 统一通用配置
3 * @param extension
4 * @return
5 */
6def baseConfig(BaseExtension extension) {
7    extension.defaultConfig {
8        minSdkVersion(Versions.minSdkVersion)
9        targetSdkVersion(Versions.targetSdkVersion)
10        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
11    }
12
13    extension.compileOptions {
14        sourceCompatibility Versions.compileOptionsJavaVersion
15        targetCompatibility Versions.compileOptionsJavaVersion
16    }
17
18    extension.lintOptions {
19        abortOnError false
20    }
21
22    extension.buildTypes {
23        release {
24            minifyEnabled false
25            proguardFiles extension.getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
26        }
27    }
28}
29
30def applyBaseConfig(Project project) {
31    project.plugins.whenPluginAdded {
32        if (it instanceof AppPlugin) {
33            def extension = project.extensions.getByType(AppExtension.class)
34            baseConfig(extension)
35        } else if (it instanceof LibraryPlugin) {
36            def extension = project.extensions.getByType(LibraryExtension.class)
37            baseConfig(extension)
38        }
39    }
40}
41
42subprojects {
43    applyBaseConfig(project)
44}
gradle多模块android