AndroidStudio2021.2.1 +Gradle7.0.0以上依赖库同一版本号管理

随着项目的不断发展,项目中的依赖也越来越多,有时可能会有几百个,这个时候对项目依赖做一个统一的管理很有必要,我们一般会有以下需求:

1、项目依赖统一管理,在单独文件中配置。

2、不同Module中的依赖版本号统一。

3、不同项目中的依赖版本号统一。

针对这些需求,目前其实已经有了一些方案:

使用循环优化Gradle依赖管理

https://juejin.cn/post/6947675376835362846#heading-2

使用buildSrc管理Gradle依赖

https://juejin.cn/post/6844903615346245646

使用includeBuild统一配置依赖版本

https://juejin.cn/post/6844904169833234439

上面的方案支持在不同Module间统一版本号,同时如果需要在项目间共享,也可以做成Gradle插件发布到远端,已经基本可以满足我们的需求。

不过Gradle7.0推出了一个新的特性,使用Catalog统一依赖版本,它支持以下特性:

1、对所有module可见,可统一管理所有module的依赖。

2、支持声明依赖bundles,即总是一起使用的依赖可以组合在一起。

3、支持版本号与依赖名分离,可以在多个依赖间共享版本号。

4、支持在单独的libs.versions.toml文件中配置依赖。

5、支持在项目间共享依赖。

使用Version Catalog

注意,Catalog仍然是一个孵化中的特性,如需使用,需要在settings.gradle中添加以下内容:

enableFeaturePreview('VERSION_CATALOGS')

从命名上也可以看出,Version Catalog其实就是一个版本的目录,我们可以从目录中选出我们需要的依赖使用。

我们可以通过如下方式使用Catalog中声明的依赖。

dependencies {

    implementation(libs.retrofit)

    implementation(libs.groovy.core)

}

在这种情况下,libs是一个目录,retrofit表示该目录中可用的依赖项。与直接在构建脚本中声明依赖项相比,Version Catalog具有许多优点:

1、对于每个catalog,Gradle都会生成类型安全的访问器,以便你在IDE中可以自动补全。(注:目前在build.gradle中还不能自动补全,可能是指kts或者开发中?)

2、声明在catalog中的依赖对所有module可见,当修改版本号时,可以统一管理统一修改。

3、catalog支持声明一个依赖bundles,即一些总是一起使用的依赖的组合。

4、catalog支持版本号与依赖名分离,可以在多个依赖间共享版本号。

声明Version Catalog

Version Catalog可以在settings.gradle(.kts)文件中声明。

dependencyResolutionManagement { versionCatalogs { libs { alias('retrofit').to('com.squareup.retrofit2:retrofit:2.9.0') alias('groovy-core').to('org.codehaus.groovy:groovy:3.0.5') alias('groovy-json').to('org.codehaus.groovy:groovy-json:3.0.5') alias('groovy-nio').to('org.codehaus.groovy:groovy-nio:3.0.5') alias('commons-lang3').to('org.apache.commons', 'commons-lang3').version { strictly '[3.8, 4.0[' prefer '3.9' } } } }

别名必须由一系列以破折号(-,推荐)、下划线 (_) 或点 (.) 分隔的标识符组成。

标识符本身必须由ascii字符组成,最好是小写,最后是数字。

值得注意的是,groovy-core会被映射成libs.groovy.core。

如果你想避免映射可以使用大小写来区分,比如groovyCore会被处理成libs.groovyCore。

具有相同版本号的依赖

在上面的示例中,我们可以看到三个groovy依赖具有相同的版本号,我们可以把它们统一起来。

dependencyResolutionManagement {

    versionCatalogs {

        libs {

version('groovy','3.0.5')

version('compilesdk','30')

version('targetsdk','30')

alias('groovy-core').to('org.codehaus.groovy','groovy').versionRef('groovy')

alias('groovy-json').to('org.codehaus.groovy','groovy-json').versionRef('groovy')

alias('groovy-nio').to('org.codehaus.groovy','groovy-nio').versionRef('groovy')

alias('commons-lang3').to('org.apache.commons','commons-lang3').version {

strictly'[3.8, 4.0['

prefer'3.9'

            }

        }

    }

}

除了在依赖中,我们同样可以在build.gradle中获取版本,比如可以用来指定compileSdk等。

android {

    compileSdk libs.versions.compilesdk.get().toInteger()

    defaultConfig {

applicationId"com.zj.gradlecatalog"

minSdk21

        targetSdk libs.versions.targetsdk.get().toInteger()

    }

}

如上,可以使用catalog统一compileSdk,targetSdk,minSdk的版本号。

依赖bundles

因为在不同的项目中经常系统地一起使用某些依赖项,所以Catalog提供了bundle(依赖包)的概念。依赖包基本上是几个依赖项打包的别名。

例如,你可以这样使用一个依赖包,而不是像上面那样声明 3 个单独的依赖项:

dependencies {

    implementation libs.bundles.groovy

}

groovy依赖包声明如下:

dependencyResolutionManagement {

    versionCatalogs {

        libs {

version('groovy','3.0.5')

version('checkstyle','8.37')

alias('groovy-core').to('org.codehaus.groovy','groovy').versionRef('groovy')

alias('groovy-json').to('org.codehaus.groovy','groovy-json').versionRef('groovy')

alias('groovy-nio').to('org.codehaus.groovy','groovy-nio').versionRef('groovy')

alias('commons-lang3').to('org.apache.commons','commons-lang3').version {

strictly'[3.8, 4.0['

prefer'3.9'

            }

bundle('groovy', ['groovy-core','groovy-json','groovy-nio'])

        }

    }

}

如上所示:添加groovy依赖包等同于添加依赖包下的所有依赖项。

插件版本

除了Library之外,Catalog还支持声明插件版本。

因为library由它们的group、artifact和version表示,但Gradle插件仅由它们的id和version标识。

因此,插件需要单独声明:

dependencyResolutionManagement {

    versionCatalogs {

        libs {

alias('jmh').toPluginId('me.champeau.jmh').version('0.6.5')

        }

    }

}

然后可以在plugins块下面使用:

plugins {

id'java-library'

id'checkstyle'

// 使用声明的插件

    alias(libs.plugins.jmh)

}

在单独文件中配置Catalog

除了在settings.gradle中声明Catalog外,也可以通过一个单独的文件来配置Catalog。

如果在根构建的gradle目录中找到了libs.versions.toml文件,则将使用该文件的内容自动声明一个Catalog。

TOML文件主要由4个部分组成:

[versions] 部分用于声明可以被依赖项引用的版本。

[libraries]部分用于声明Library的别名。

[bundles]部分用于声明依赖包。

[plugins] 部分用于声明插件。

如下所示:

[versions]

groovy ="3.0.5"

checkstyle ="8.37"

compilesdk ="30"

targetsdk ="30"

[libraries]

retrofit ="com.squareup.retrofit2:retrofit:2.9.0"

groovy-core = { module ="org.codehaus.groovy:groovy", version.ref ="groovy"}

groovy-json = { module ="org.codehaus.groovy:groovy-json", version.ref ="groovy"}

groovy-nio = { module ="org.codehaus.groovy:groovy-nio", version.ref ="groovy"}

commons-lang3 = { group ="org.apache.commons", name ="commons-lang3", version = { strictly ="[3.8, 4.0[", prefer="3.9"} }

[bundles]

groovy = ["groovy-core","groovy-json","groovy-nio"]

[plugins]

jmh = { id ="me.champeau.jmh", version ="0.6.5"}

如上所示,依赖可以定义成一个字符串,也可以将module与version分离开来。

其中versions可以定义成一个字符串,也可以定义成一个范围,详情可参见rich-version。

https://docs.gradle.org/current/userguide/rich_versions.html#rich-version-constraints

[versions]

my-lib = { strictly ="[1.0, 2.0[", prefer ="1.2"}

在项目间共享Catalog

Catalog不仅可以在项目内统一管理依赖,同样可以实现在项目间共享。

例如我们需要在团队内制定一个依赖规范,不同组的不同项目需要共享这些依赖,这是个很常见的需求。

通过文件共享

Catalog支持通过从Toml文件引入依赖,这就让我们可以通过指定文件路径来实现共享依赖。

如下所示,我们在settins.gradle中配置如下:

dependencyResolutionManagement {

    versionCatalogs {

        libs {

from(files("../gradle/libs.versions.toml"))

        }

    }

}

此技术可用于声明来自不同文件的多个目录:

dependencyResolutionManagement {

    versionCatalogs {

// 声明一个'testLibs'目录, 从'test-libs.versions.toml'文件中

        testLibs {

from(files('gradle/test-libs.versions.toml'))

        }

    }

}

发布插件实现共享

虽然从本地文件导入Catalog很方便,但它并没有解决在组织或外部消费者中共享Catalog的问题。

我们还可能通过Catalog插件来发布目录,这样用户直接引入这个插件即可。

Gradle提供了一个Catalog插件,它提供了声明然后发布Catalog的能力。

1. 首先引入两个插件

plugins {

id'version-catalog'

id'maven-publish'

}

然后,此插件将公开可用于声明目录的catalog扩展。

2. 定义目录

上面引入插件后,即可使用catalog扩展定义目录。

catalog {

// 定义目录

    versionCatalog {

from files('../libs.versions.toml')

    }

}

然后可以通过maven-publish插件来发布目录。

3. 发布目录

publishing {

    publications {

        maven(MavenPublication) {

groupId ='com.zj.catalog'

artifactId ='catalog'

version ='1.0.0'

            from components.versionCatalog

        }

    }

}

我们定义好groupId,artifactId,version,from就可以发布了。

我们这里发布到mavenLocal,你也可以根据需要配置发布到自己的maven。

以上发布的所有代码可见:Catalog发布相关代码。

https://github.com/shenzhen2017/GradleCatalog

4. 使用目录

因为我们已经发布到了mavenLocal,在仓库中引入mavenLocal就可以使用插件了。

# settings.gradle

dependencyResolutionManagement {

//...

    repositories {

        mavenLocal()

//...

    }

}

enableFeaturePreview('VERSION_CATALOGS')

dependencyResolutionManagement {

    versionCatalogs {

        libs {

from("com.zj.catalog:catalog:1.0.0")

// 我们也可以重写覆盖catalog中的groovy版本

version("groovy","3.0.6")

        }

    }

}

如上就成功引入了插件,就可以使用catalog中的依赖了。

这样就完成了依赖的项目间共享,以上使用的所有代码可见:Catalog使用相关代码。

https://github.com/shenzhen2017/GradleCatalog/tree/feature/useCatalog

总结

项目间共享依赖是比较常见的需求,虽然我们也可以通过自定义插件实现,但还是不够方便

Gradle官方终于推出了Catalog,让我们可以方便地实现依赖的共享,Catalog主要具有以下特性:

1、对所有module可见,可统一管理所有module的依赖。

2、支持声明依赖bundles,即总是一起使用的依赖可以组合在一起。

3、支持版本号与依赖名分离,可以在多个依赖间共享版本号。

4、支持在单独的libs.versions.toml文件中配置依赖。

5、支持在项目间共享依赖。

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

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,599评论 18 139
  • 依赖管理是Gradle的一个亮点。在最好的情况下,你只需要在构建文件中添加一行代码,Gradle就可以从远程仓库下...
    sollian阅读 5,115评论 0 3
  • 依赖管理 依赖管理是Gradle最闪耀的地方,最好的情景是,你仅仅只需添加一行代码在你的build文件,Gradl...
    木木00阅读 459评论 1 6
  • 概述 Gradle是新一代构建工具,从0.x版本一路走来虽然国内可寻的资料多了一些,但都是比较碎片化的知识。官方的...
    三也视界阅读 57,265评论 0 39
  • 一、Gradle定义的规则 Gradle是项目自动构建工具,更是一个框架;它作为框架,定义了流程和规则. 它在构建...
    永安里_阅读 836评论 0 1