把重要弥补放在前面(2022年6月17日):该功用测验下来发现,需求把gradle文件夹下的gradle-wrapper.properties中,gradle版别改为7.4.2以上才能够,否则无法解析‘

(2023年8月2日)最新的喜爱把一切依靠打包成Toml,复制到对应的项目进行处理,因为发布MavenCentral还得等审阅、同步,太累

前语

因为自己喜爱用新技术,也喜爱研讨新技术,前阵子Gradle晋级至7.2.1后,在研讨更新后改了什么,怀着好奇心,翻开了Gradle官方文档,随便看看发现了一个依靠统一办理的全新办法-VERSION_CATALOG,喜爱捣鼓的我,开端研讨怎样运用。

查看官网文档

首先我在官方文档看了一下,然后CSDN等常用的技术文章论坛搜了一下,几乎是清一色的官方文档直译,偶然带点小引荐,我其时的表情是:

如何使用Gradle7.0+的VERSION_CATALOG
那我为何不这样:
如何使用Gradle7.0+的VERSION_CATALOG
不满足于此的我,着手自己研讨,官方文档也是截取了部分代码,有些看起来仍是云里雾里的。

根据官方文档,我结合本身项目写了这篇文章,给自己存点干活,好了废话不多说,上干货。

干货部分

官网文档地址先给大佬奉上,基本上父类目下的都有用,能够先看一下官方文档,学习一下。 有言在先,Catalog目前处于预览版别,需求手动开启。别的,我现已把grardle文件从groovy搬迁至了kts,能够看官方文档进行搬迁,或者搜一下相关文章仍是许多的,我在这儿就不多说了。

开启功用

  1. 在项目根目录找到【settings.gradle.kts】文件,开启VERSION_CATALOG
	enableFeaturePreview("VERSION_CATALOGS")
  1. 这个时分咱们能够同样在settings.gradle.kts,参加下面这段代码
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
    //留意,重点在这儿
    versionCatalogs {
        create("lib") {
            library("core-ktx", "androidx.core", "core-ktx").version("1.7.0")
            library("appcompat", "androidx.appcompat", "appcompat").version("1.4.1")
        }
    }
}

其中,create中的lib为创立的目录名,能够自己定义,

简单运用

第一种,有点类似平时依靠的那样

	//入参是别号和完好的依靠和版别号,比方上面的appcompat能够写成:
	versionCatalogs {
        create("lib") {
            library("appcompat","androidx.appcompat:appcompat:1.4.1")
        }
    }

第二种,

	//入参为{别号},{group},{artifact}
	versionCatalogs {
		create("lib") {
			library("core-ktx", "androidx.core", "core-ktx").version("1.7.0")
		}
	}

然后就能够在每一个module里边的build.gradle.kts中运用依靠,比方我自己项目的module-base

dependencies {
	api(lib.core.ktx)
    api(lib.appcompat)
}

当然,你能够创立多个目录,比方,你能够把androidx的内容单独放置,

//settings.gradle.kts
	versionCatalogs {
		crete("lib"){
	        library("fastjson", "com.alibaba", "fastjson").version("1.2.79")
	        library("fastjson2", "com.alibaba.fastjson2", "fastjson2").version("2.0.4")
	        library("fastjson2-kotlin", "com.alibaba.fastjson2", "fastjson2-kotlin").version("2.0.4")
		}
		create("androidx"){
			library("core-ktx", "androidx.core", "core-ktx").version("1.7.0")
			library("appcompat", "androidx.appcompat", "appcompat").version("1.4.1")
			library("activity-ktx", "androidx.activity", "activity-ktx").version("1.4.0")
			library("fragment-ktx", "androidx.fragment", "fragment-ktx").version("1.4.1")
		}
	}

留意:我测验过AndroidX,发现没有生成对应的,所以称号有或许有必要小写,这个能够自己测验一下

引进就能够采用新办法了

//任何module下的 build.gradle.kts
dependencies{
	api(androidx.core.ktx)
	api(lib.fastjson2.kotlin)
}

有言在后,必定重要,官方对alias命名有一套规矩,详细如下(纯翻译): 别号有必要由一系列标识符组成,由破折号 ( -, 引荐)、下划线 ( _) 或点 ( .) 分隔。标识符本身有必要由 ascii 字符组成,最好是小写,最终是数字。 例如:

  • appcompat是一个有用的别号
  • core.kts是一个有用的别号
  • fastjson2-kotlin是一个有用的别号
  • androidx.fragment.kts也是一个有用的别号
  • this.#is.not!

然后为每个子组生成别号会创立成类型安全拜访器。例如,给定名为 的版别目录中的以下别号libs: appcompat,core-ktx,activity-kts,androidx.fragment.kts 将会主动生成一下类型安全的拜访器:

  • lib.appcompat
  • lib.core.kts
  • lib.activity.kts
  • lib.androidx.fragment.kts

前缀lib来自版别目录称号。

假如您想防止生成子组拜访器,咱们主张依靠巨细写来区别。例如,别号activityKts,coreKtxfastjson2Kotlin将别离映射到libs.groovyCore,libs.groovyJsonlibs.groovyXml拜访器。

至此,简单的依靠引进咱们就完成了。

具有相同版别号的依靠

当咱们遇到部分依靠具有相同版别号时,我个人认为还得加一个判别是,来源相同,比方我用的coil图片加载结构,那其中会涉及到两个依靠:io.coil-kt.coilio.coil.kt.coil-gif,并且他们的版别号一致,则能够采用如下办法:

        version("coil", "2.1.0")
        library("coil", "io.coil-kt", "coil").versionRef("coil")
        library("coil-gif", "io.coil-kt", "coil-gif").versionRef("coil")
        //包括运用kotlin开发言语的工程师,如下两个也是常备的依靠
		version("kotlin", "1.7.0")
        library("stdlib", "org.jetbrains.kotlin", "kotlin-stdlib").versionRef("kotlin")
        library("reflect", "org.jetbrains.kotlin", "kotlin-reflect").versionRef("kotlin")

单独申明的version也能够经过类型安全的拜访器取得,比方minSdk,就能够大局统一办理最低适配版别等

	#settings.gradle.kts
	version("minSdk","24")
	version("targetSdk","31")
	#build.gradle.kts(:app)
	android {
		defaultConfig {
			minSdk = libs.versions.minSdk.get().toInt()
			targetSdk = libs.versions.targetSdk.get().toInt()
			...
		}
	}

包的概念

运用kotlin言语作为开发言语的都有这样的状况:

val kotlinVer = "1.7.0"
val coroutineVer = "1.6.2"
dependencies{
	api(kotlin("stdlib", version = kotlinVer))
    api(kotlin("reflect", version = kotlinVer))
    api("org.jetbrains.kotlinx:kotlinx-coroutines-core:${coroutineVer}")
    api("org.jetbrains.kotlinx:kotlinx-coroutines-android:${coroutineVer}")
}

kt和协程依靠的一大堆,还有第三方比方友盟,像我的一个项目依靠了21个跟友盟相关的包。假如你用了VERSION_CATALOG,就能够这样写:

dependencies{
	api(lib.bundles.kotlin)
    api(lib.bundles.coroutines)
    //一切module只需求这一句就能依靠一切
    api(lib.bundles.umeng)
}

是不是简练了许多,这便是它的bundle包机制,那么怎样写呢?咱们回到settings.gradle.kts,在参加依靠后,在下面一同参加bundle,办法需求两个参数,alias(别号),List<String>(子依靠的别号集合)

    versionCatalog {
        version("kotlin", "1.7.0")
        library("stdlib", "org.jetbrains.kotlin", "kotlin-stdlib").versionRef("kotlin")
        library("reflect", "org.jetbrains.kotlin", "kotlin-reflect").versionRef("kotlin")
        //bundle的入参别离为,alias(别号),需求依靠的别号集合
        bundle("kotlin", listOf("stdlib", "reflect"))
        bundle(
                "umsdk", listOf(
                    "umsdk-common",
                    "umsdk-asms",
                    ...
                    "umsdk-huawei-push",
                    "umsdk-huawei-umengaccs",
                    "umsdk-vivo-push",
                    "umsdk-vivo-umengaccs",
                    "umsdk-oppo-push",
                    "umsdk-oppo-umengaccs",
                )
        )
        //21个依靠就不放出来了
}

这便是bundle的写法,官方给了bundle的概念,让依靠版别统一的办理愈加的简练易懂。

tips:不同类型的别号是能够重复的,他们之间相互独立。 答应以下办法运用:

  • version("kotlin",""),
  • library("kotlin",""),
  • bundle("kotlin",listOf("",""))

你以为它只能办理库吗?不!还有插件!

没错,除了库,VERSION_CATALOG还支持声明插件版别,仅有区别是,库由他们的groupartifactversion标识,而Gradle插件仅只有他们的idversion标识。因而,他们需求额定声明,不能用library,对此,官方供给了plugin办法,如下:

    dependencyResolutionManagement {
        versionCatalogs {
            create("libs") {
            	version("ksp", "1.7.0-1.0.6")
                plugin("ksp", "com.google.devtools.ksp").versionRef("ksp")
				version("kotlin", "1.7.0")
            	library("stdlib", "org.jetbrains.kotlin", "kotlin-stdlib").versionRef("kotlin")
            	library("reflect", "org.jetbrains.kotlin", "kotlin-reflect").versionRef("kotlin")
            	bundle("kotlin", listOf("stdlib", "reflect"))
                plugin("kotlin-parcelize", "org.jetbrains.kotlin.plugin.parcelize").versionRef("kotlin")
            	plugin("kotlin-serialization", "org.jetbrains.kotlin.plugin.serialization").versionRef("kotlin")
            }
        }
    }

运用办法:

#build.gradle.kts(:app)
plugins{
	...
	alias(libs.plugins.ksp)
}
ksp{
}

而且有没有发现,还能跟库的依靠版别保持一致,能够一同版别号,有没有很nice的感觉?

如何使用Gradle7.0+的VERSION_CATALOG

可是现实是有或许会呈现如下状况:

如何使用Gradle7.0+的VERSION_CATALOG
原因未知:处理方案测验替换Gradle版别,替换JDK,清理缓存,重启电脑。。。。。无效,可是第一次运用的时分并没有呈现这个问题,所以有待深入研讨,究竟AS时不时就会抽风找不到文件,不过不重要,仍然能用,便是这个爆红让我强迫症犯了,所以一般我不用,所以仍是删了删了 ,了解了就行,究竟kts还没研讨透。

Tips:增加这个 @Suppress("DSL_SCOPE_VIOLATION")即可处理

TOML文件格式

Gradle的VERSION_CATALOG供给了一个TOML文件来声明一个目录,TOML文件由4个首要部分组成:

  • 该[versions]部分用于声明能够被依靠项引证的版别
  • 该[libraries]部分用于声明坐标的别号
  • 该[bundles]部分用于声明依靠包、
  • 该[plugins]部分用于声明插件

例如:

[versions]
coil = "2.1.0"
kotlin = "1.7.0"
[libraries]
activity-ktx = {group = "androidx.activity", name = "activity-ktx", version = "1.4.0" }
reflect = {group = "org.jetbrains.kotlin", name = "kotlin-reflect", version.ref = "kotlin" }
[bundles]
coil = ["coil", "coil-gif"]
coroutines = ["kotlinx-coroutines-core", "kotlinx-coroutines-android"]

看一下基本上就学会怎样写了,编写了TOML文件就能够经过TOML文件进行多个项目进行同享,别着急写,看完文章再写不迟。

同享目录

版别目录在单个构建(或许是多项目构建)中运用,但也能够在构建之间同享。例如,一个安排或许想要创立来自不同团队的不同项目或许运用的依靠关系目录。

从TOML文件导入目录

版别目录构建器 API支持包括来自外部文件的模型。假如需求,这使得重用主构建的目录成为或许buildSrc。例如,该buildSrc/settings.gradle(.kts)文件能够运用以下办法包括此文件:

dependencyResolutionManagement {
    versionCatalogs {
        create("libs") {
            from(files("../gradle/libs.versions.toml"))
        }
    }
}

插件

尽管本地TOML文件导入办法很便利,可是现在都是主动集成的年代,别的手动去写TOML文件又累又费事,程序员都是一个想方设法找偷闲办法的生物,Gradle给咱们供给了两个插件version-catalog和用于发布的maven-publish。 咱们先引进:

#build.gradle.kts(:project)
plugins {
    `version-catalog`
    `maven-publish`
}

然后应用插件并声明目录中的依靠和插件,我便是在这儿考虑了一下,官方事例就很古怪,没有说上下文,让人很利诱

//先看官方的
catalog {
    // declare the aliases, bundles and versions in this block
    versionCatalog {
        library("my-lib", "com.mycompany:mylib:1.2")
    }
}
//在看我的
catalog {
    // declare the aliases, bundles and versions in this block
    versionCatalog {
        version("coroutines", "1.6.2")
        library("kotlinx-coroutines-core", "org.jetbrains.kotlinx", "kotlinx-coroutines-core").versionRef("coroutines")
        library("kotlinx-coroutines-android", "org.jetbrains.kotlinx", "kotlinx-coroutines-android").versionRef("coroutines")
        bundle("coroutines", listOf("kotlinx-coroutines-core", "kotlinx-coroutines-android"))
    }
}

实际上,这个插件是用于主动生成TOML文件的,所以内部的依靠便是你项目所需的依靠,等同于settings.gradle.kts中声明的那些,下一步翻开Android Studio的右侧边栏的Gradle,找到坐落【Tasks】【build】【generateCatalogAsToml】,双击运转

如何使用Gradle7.0+的VERSION_CATALOG

履行完Tasks后会在对应的module中的build目录下生成一个文件夹version-catalog,自己写在project下的build.gradle.kts,所以主动生成的目录在项目根目录的build文件夹下:

如何使用Gradle7.0+的VERSION_CATALOG

有个文件名为libs.versions.toml文件,文件名为默许的,官方也有更改文件名的API,我觉得没必要,然后能够经过应用maven-publish插件并将发布装备为运用该versionCatalog组件来发布这样的目录。 mavenCentral发布流程我就不在这儿说了,需求的话搜一下仍是有许多文章的。 上传至MavenCentral后,回到settings.gradle.kts,将原有的依靠等改为:

versionCatalogs {
	create("lib") {
		from("你的groupId:你的artifactId:你的版别")
		//当然这儿仍然能够弥补别的依靠
	}
}

tips:依靠今后就能够吧原先的注释掉了,留着是便利下次生成TOML和上传maven,别的,maven-publish的发布主动会履行generateCatalogAsToml,一步到位。

好了,干货就大约这些,也是选取了一些比较常用的和结合了本身项目写的文章,写作次数不多,迁就看看吧,有问题有想法大家一同评论。 最终附上我自己的版别操控库,仅供参考:VersionControlPlugin