Gradle 之统一管理依赖(kotlin+buildSrc)

背景

随着项目越来越大,module 越来越多,依赖的库也越来越多,依赖管理也越来越混乱。

管理 Gradle 依赖三板斧

一、原始粗暴式

module/build.gradle 直接引入,就像下面一样:

plugins {
    id 'com.android.library'
    id 'kotlin-android'
}

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.2"

    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 30
        versionCode 1
        versionName "1.0.0"
        ...
    }
    ...
}

dependencies {

    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.3.2'

    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.3.0'

    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
}

方便快捷,依赖的时候 gtihub 上复制粘贴一气呵成,我们在这里就不讨论重复配置的问题了,只是如果需要进行版本升级的时候大家就知道这样写的酸爽了。

二、ext 进化式

Gradle 提供了 ext 关键字可以让我们去定义自身所需要的扩展属性。说白话就是我们可以通过 ext 关键字对我们工程中的依赖进行全局配置。

1. 直接在根目录下的 build.gradle 中编写 ext
ext {
    versions = [
            compileSdkVersion: 30,
            buildToolsVersion: "30.0.2",
            minSdkVersion    : 21,
            targetSdkVersion : 30,
            versionCode      : 1,
            versionName      : "1.0.0",

            kotlin_version: "1.4.30",
            core_ktx      : "1.3.2",
            appcompat     : "1.2.0",
            material      : "1.3.0",
            retrofit      : "2.9.0"
    ]

    libs = [
            kotlin_stdlib: "org.jetbrains.kotlin:kotlin-stdlib:${versions.kotlin_version}",
            core_ktx:"androidx.core:core-ktx:1.3.2:${versions.core_ktx}",
            appcompat:"androidx.appcompat:appcompat:${versions.appcompat}",
            material:"com.google.android.material:material:${versions.material}",
            retrofit:"com.squareup.retrofit2:retrofit:${versions.retrofit}"
    ]
}

module 中的 build.gradle,如下:

plugins {
    id 'com.android.library'
    id 'kotlin-android'
}

android {
    compileSdkVersion versions.compileSdkVersion
    buildToolsVersion versions.buildToolsVersion

    defaultConfig {
        minSdkVersion versions.minSdkVersion
        targetSdkVersion versions.targetSdkVersion
        versionCode versions.versionCode
        versionName versions.versionName
        ...
    }
    ...
}

dependencies {

    implementation libs.kotlin_stdlib
    implementation libs.core_ktx
    implementation libs.appcompat
    implementation libs.material

    implementation libs.retrofit
}

这样,所有的 module 需要更新依赖库的时候,去修改 ext 下的代码即可,当然,如果是新增的话,还要在 module 下进行依赖,这个不必多说。

2. 在另一个 gradle 脚本中进行编写 ext

随着依赖项越来越多,ext 中的代码也越来越庞大,为了更好地管理。我们会把代码写在一个 .gradle 文件中,一般在开源项目中是 config.gradle 或者 versions.gradle。以 config.gradle 为例(放在根目录下):


  • config.gradle
ext {
    versions = [
            compileSdkVersion: 30,
            buildToolsVersion: "30.0.2",
            minSdkVersion    : 21,
            targetSdkVersion : 30,
            versionCode      : 1,
            versionName      : "1.0.0",

            kotlin_version: "1.4.30",
            core_ktx      : "1.3.2",
            appcompat     : "1.2.0",
            material      : "1.3.0",
            retrofit      : "2.9.0"
    ]

    libs = [
            kotlin_stdlib: "org.jetbrains.kotlin:kotlin-stdlib:${versions.kotlin_version}",
            core_ktx:"androidx.core:core-ktx:1.3.2:${versions.core_ktx}",
            appcompat:"androidx.appcompat:appcompat:${versions.appcompat}",
            material:"com.google.android.material:material:${versions.material}",
            retrofit:"com.squareup.retrofit2:retrofit:${versions.retrofit}"
    ]
}
  • 在根目录的 build.gradle 文件中的头部加上 apply from: config.gradle
  • 在 module 中 build.gradle 应用依赖项,如下
    id 'com.android.library'
    id 'kotlin-android'
}

android {
    compileSdkVersion rootProject.ext.versions["compileSdkVersion"]
    buildToolsVersion rootProject.ext.versions["buildToolsVersion"]

    defaultConfig {
        minSdkVersion rootProject.ext.versions["minSdkVersion"]
        targetSdkVersion rootProject.ext.versions["targetSdkVersion"]
        versionCode rootProject.ext.versions["versionCode"]
        versionName rootProject.ext.versions["versionName"]
        ...
    }
    ...
}

dependencies {

    implementation rootProject.ext.libs["kotlin_stdlib"]
    implementation rootProject.ext.libs["core_ktx"]
    implementation rootProject.ext.libs["appcompat"]
    implementation rootProject.ext.libs["material"]

    implementation rootProject.ext.libs["retrofit"]
}

三、kotlin + buildSrc 式

ext 可以帮我们很好地解决了管理依赖的问题,美中不足的是它不支持点击跳转、自动补全的问题。这就轮到 buildSrc 大显身手了。对于 buildSrc 写过 gradle 插件的同学都说好。

运行 gradle 时,它首先会检查项目中是否存在一个叫 buildSrc 的目录,如果有的话,gradle 会自动编译并测试这段代码,并将其放入构建脚本的类路径中。

1. 在根目录下创建 buildSrc 目录
2. 新建文件 build.gradle.kts,并同步 gradle,如下:
plugins {
    `kotlin-dsl`
}
repositories {
    jcenter()
}
3. 创建 /src/main/java/Dependencies.kt 文件,如下:
4. 在 Dependencies.kt 文件中编写依赖管理代码,如下:
object BuildVersion {
    const val compileSdk = 30
    const val buildTools = "30.0.2"
    const val minSdk = 21
    const val targetSdk = 30
    const val versionCode = 1
    const val versionName = "1.0.0"
}

object Versions {
    const val kotlin = "1.4.30"
    const val core_ktx = "1.3.2"
    const val appcompat = "1.2.0"
    const val material = "1.3.0"
    const val retrofit = "2.9.0"
}

object Libs {
    const val kotlin_stdlib = "org.jetbrains.kotlin:kotlin-stdlib:${Versions.kotlin}"
    const val core_ktx = "androidx.core:core-ktx:1.3.2:${Versions.core_ktx}"
    const val appcompat = "androidx.appcompat:appcompat:${Versions.appcompat}"
    const val material = "com.google.android.material:material:${Versions.material}"
    const val retrofit = "com.squareup.retrofit2:retrofit:${Versions.retrofit}"
}

5. 在 module 中 build.gradle 应用依赖项,如下
plugins {
    id 'com.android.library'
    id 'kotlin-android'
}

android {
    compileSdkVersion BuildVersion.compileSdk
    buildToolsVersion BuildVersion.buildTools

    defaultConfig {
        minSdkVersion BuildVersion.minSdk
        targetSdkVersion BuildVersion.targetSdk
        versionCode BuildVersion.versionCode
        versionName BuildVersion.versionName
        ...
    }

    ...
}

dependencies {

    implementation Libs.kotlin_stdlib
    implementation Libs.core_ktx
    implementation Libs.appcompat
    implementation Libs.material

    implementation Libs.retrofit
}

参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容