Gradle构建项目统一依赖

728 阅读3分钟

一、概述

为了统一管理项目的依赖库,我们现在的做法基本都是自定义一个config.gradle文件,把所有的依赖都放在这里边,让每个module去引用,但是这样对于项目的拓展不够灵活,而且一些大项目这个文件可能要一二百行代码,也便于维护,下边我们来说说 如何管理我们的配置依赖以及如何管理我们的庞大的build.gradle(配置 product flavor ,格式化apk文件命名以及路径,动态生成版本号,如果 jenkins 还需要配置一些独立的逻辑那么这个文件会越来越长)文件。

二、知识点介绍

在说解决方案之前先说下用到的知识点吧, 1、Kotlin DSL:Kotlin 1.3.20 发布之后,并在多平台项目中提供了对Kotlin DSL构建脚本的支持。由于现在Kotlin是Android官方推荐语言,因此使用Kotlin构建Gradle脚本有利于整个项目开发语言的统一,不需要另外学习Groovy的语法
2、buildSrc:运行 Gradle 时会检查项目中是否存在一个名为 buildSrc 的目录,执行编译buildSrc是在所有的build.gradle编译之前执行,所以可以把项目的配置文件放在这里统一管理,有module的每一个gradle文件去调用。
3、Composing builds:buildSrc有一个弊端就是由于是被所有module公有引用的 所以编译会比较慢,而Composing builds可以用自定义 plugin + includeBuild插件的形式 让每一个module选择性依赖,从而提高了编译效率,这也是现在普遍选择Composing builds 的原因之一吧,而且做插件开发 也用到Composing builds。
可以根据项目大小等实际情况选择使用buildSrc还是Composing builds

三、buildSrc方式

1、项目根目录下新建一个名为 buildSrc 的文件夹
2、在 buildSrc 文件夹里创建名为 build.gradle.kts 的文件
文件内容:

plugins {    `kotlin-dsl`}repositories {    jcenter()}

3、buildSrc下新建目录src\main\kotlin
4、把setting.gradle 重命名为 setting.gradle.kts 所有的Kotlin DSL 文件,都是以.kts 为文件名后缀 然后修改文件里面的内容:

include (":app")rootProject.buildFileName = "build.gradle.kts"

把原本的 “:” 改成了 “()” 这也是Kotlin DSL和Groovy语法的差别之一
5、把build.gradle 重命名为 build.gradle.kts
修改内容

buildscript {    val kotlin_version = "1.3.61" // #1    repositories {        google()        jcenter()    }    dependencies {        classpath("com.android.tools.build:gradle:4.0.0-beta01")  // #2        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")        // NOTE: Do not place your application dependencies here; they belong        // in the individual module build.gradle files    }}allprojects {    repositories {        google()        jcenter()    }}tasks.register("clean", Delete::class) {  // #3    delete(rootProject.buildDir)}

这里主要修改的就是三点,我已经在代码中标识出来了:

ext改成 val,val是Kotlin不可变变量的关键字 classpath 的 单引号 改为 双引号 task 同样需要改成 Kotlin 的语法

6、在src/main/kotlin目录下创建依赖文件 官方推荐我们使用这个文件夹来管理整个项目的依赖,也就是说,我们可以在这个路劲定义多个和依赖相关的类。

那可以根据项目情况创建多个依赖文件给module的build.gradle文件引用, 创建Dependencies.kt文件

object Apps {    const val compileSdk = 29    const val minSdk = 21    const val targetSdk = 29    const val versionCode = 1    const val versionName = "1.0.0"}object Versions {    const val gradle = "3.5.3"    const val kotlin = "1.3.61"    const val appcompat = "1.0.2"        /* test */    const val junit = "4.12"}object Libs {    const val kotlin = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${Versions.kotlin}"    const val appcompat = "androidx.appcompat:appcompat:${Versions.appcompat}"}object TestLibs {    const val junit = "junit:junit:${Versions.junit}"}

然后我们就可以在App的build.gradle.kts里面用上这些定义的常量了

7、修改App的build.gradle文件
更名为build.gradle.kts

// 省略代码android {    compileSdkVersion(Apps.compileSdk)    defaultConfig {        applicationId = ""        minSdkVersion(Apps.minSdk)        targetSdkVersion(Apps.targetSdk)        versionCode = Apps.versionCode        versionName = Apps.versionName    } // 省略代码}dependencies {    // android supports    implementation(Libs.appcompat)    // test    testImplementation(TestLibs.junit)}

小结
如果项目有多个Modlue,而且依赖关系也很复杂,那么我们可以在buildSrc/src/main/kotlin 目录下多定义几个kt文件,用于管理不同的依赖。这里就不展开了。

三、Composing builds方式

这种方式主要是通过自定义 plugin + includeBuild的方式来实现的。

1、我们新建一个 module,命名为 version ,并将上边的方式二的 buildSrc 的代码转移过来

class DependencyVersionPlugin : Plugin<Project> {    override fun apply(project: Project) {这里不写插件用不到可以忽略 插件名字随便起    }}

2、在 version 的 build.gradle 文件加入

gradlePlugin {    plugins {        version {            id = 'com.test.version'            implementationClass = 'com.test.version.DependencyVersionPlugin'        }    }}

3、在 settings.gradle 加入 includeBuild("version")

includeBuild("version")rootProject.name='VersionControlDemo'include ':app'include ':lib'

4、接下来在需要引用的 module 中引入该插件

plugins {    id "com.test.version"}

然后在android{}dependencies{}等里边就可以引用了,方式同buildSrc。
另外像构建的product flavor 多渠道打包也可以单独写个kt文件去配置

总结

经过这两种方式这么一优化我们的build.gradle 文件看着整洁多了,更便于我们去管理依赖了,当然这些方式并不适合所有的项目,看自己的项目情况而选择吧,如果需要写插件推荐用Composing builds方式(像字节码插装插件不需要打包上传可以module里引用插件调试、apt插件)。

有什么问题欢迎留言沟通讨论。

关注我获取更多知识或者投稿