新一代版本依赖管理Vesion Catalog的探索与实践

2024-01-09 02:10

本文主要是介绍新一代版本依赖管理Vesion Catalog的探索与实践,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

前段时间使用新版本的Android Studio创建了个项目想测试点东西,项目创建后发现整个Gradle的依赖管理发生了巨大的变化。
先说一下我使用的Android Studio的版本如下。
在这里插入图片描述
创建项目后主要变化如下:

  1. 原本的.gradle变成了.gradle.kts,也就是说以后肯定是以kts脚本为主了。kts相较于grovvy使用起来更加方便,语言统一,且有提示。
  2. AGP版本升到了8+
  3. 版本依赖变成了下面这个样子
    在这里插入图片描述
    点击依赖发现会跳转到 gradle目录下的libs.versions.toml 文件内
    在这里插入图片描述

这个libs.version.toml实际上是Gradle新版本提供的一种依赖管理方式,详情可以看 version catalog 官方文档

在version catalog 之前,实际上在Android中的Gradle依赖管理还有以下几种方式

  1. 直接依赖 最原始的方式,维护依赖版本时很麻烦
  2. 在ext中声明依赖的信息,然后在依赖处使用ext中声明的变量进行依赖管理,初步解决了依赖版本统一的问题,但写起来没提示,还是很麻烦
  3. 通过内置的buildSrc插件进行依赖管理,在插件内部通过代码维护依赖信息,使用依赖时导包使用即可,本质上就是个静态变量的方式。这种方式算是比较友好了,写依赖的时候有提示,在编译期会进行校验,由于每次更改都会导致全量编译,因此对编译速度有一定的影响。
  4. 使用Include build,可以像buildSrc那样把依赖信息维护在代码内,使用时也跟跟buildSrc类似,但是编译速度要更快,也有提示以及点击跳转等功能。

前面几种方式我都用过,在version catalog出来之前的很长一段时间我用的都是Include build这种方式,但是其还有一个问题没法解决就是根目录下的插件版本没办法管理到,如图所示,例如我希望把therouter的插件版本也管理起来,因为他的版本我已经在com.yzq.dependency-manager中声明过了。
在这里插入图片描述
但是不管是buildSrc还是Include build,都是编译期才生效,并且其生命周期也都在根目录build.geadle执行之后,所以没办法把插件相关的配置给维护起来。

而 Vesion Catalog 就解决了这个问题。

Vesion Catalog的使用和发布

Version Catalog的使用非常简单,官方文档介绍的已经非常详细了,推荐直接去看 官方文档 即可。
需要注意的是使用Version Catalog对Gradle的版本是有要求的,推荐直接在AGP8以上的版本使用,没有什么奇怪的限制。

这里我门快速过一下使用方式

方式一

直接在settings.gradle.kts中声明versionCatalogs以及相关的配置信息即可

dependencyResolutionManagement {repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)repositories {google()mavenCentral()}versionCatalogs {create("androidLibs") {/*声明版本号*/version("minSdk", "21")version("compileSdk", "33")version("targetSdk", "33")version("kotlin", "1.8.22")/*** 声明依赖库*  方式一:别名, 依赖库的具体坐标和版本*  方式二:别名, group,artifact,version*/library("androidx-appcompat", "androidx.appcompat:appcompat:1.3.1")//方式一library("androidx-core-ktx", "androidx", "core:core-ktx").version("1.6.0")//方式二/*把依赖库打包 一起依赖*/bundle("androidx", listOf("androidx-appcompat", "androidx-core-ktx"))/*声明插件*/plugin("android-library", "com.android.library").version("8.0.2")plugin("kotlin-android", "org.jetbrains.kotlin.android").versionRef("kotlin")}}
}

随后使用方式如下:

plugins {
//    id("com.android.library")
//    id("org.jetbrains.kotlin.android")/*依赖插件 等同于上面注释掉的代码*/alias(androidLibs.plugins.android.library)alias(androidLibs.plugins.kotlin.android)
}android {namespace = "com.yzq.mylibrary2"compileSdk = androidLibs.versions.compileSdk.get().toInt()
}dependencies {/*单独依赖*/implementation(androidLibs.androidx.core.ktx)implementation(androidLibs.androidx.appcompat)/*打包依赖*/implementation(androidLibs.bundles.androidx)
}

在添加依赖时是有提示的,同时把插件的版本也管理起来了。

方式二

方式二是官方推荐的方式,就是在toml文件中管理依赖。创建新项目时默认就是这种方式,默认的文件路径在文章开头也给出了,是在gradle文件夹里。
在这里插入图片描述

至于写法也很简单,这里不赘述了。

  • [versions]就是声明版本的
  • [libraries]就是声明依赖库的
  • [plugins]就是声明插件的
  • [bundles]就是打包依赖,用来简化依赖

示例如下:

[versions]
agp = "8.2.0-alpha10"
kotlin = "1.8.21"
core-ktx = "1.9.0"
junit = "4.13.2"
androidx-test-ext-junit = "1.1.5"
espresso-core = "3.5.1"
appcompat = "1.6.1"
material = "1.9.0"
constraintlayout = "2.1.4"
lifecycle-livedata-ktx = "2.6.1"
lifecycle-viewmodel-ktx = "2.6.1"
navigation-fragment-ktx = "2.6.0"
navigation-ui-ktx = "2.6.0"[libraries]
core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "core-ktx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-test-ext-junit" }
espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espresso-core" }
appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
lifecycle-livedata-ktx = { group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version.ref = "lifecycle-livedata-ktx" }
lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycle-viewmodel-ktx" }
navigation-fragment-ktx = { group = "androidx.navigation", name = "navigation-fragment-ktx", version.ref = "navigation-fragment-ktx" }
navigation-ui-ktx = { group = "androidx.navigation", name = "navigation-ui-ktx", version.ref = "navigation-ui-ktx" }[plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" }
kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }[bundles]
androidX = { modules = ["core-ktx", "appcompat", "material", "constraintlayout", "lifecycle-livedata-ktx", "lifecycle-viewmodel-ktx", "navigation-fragment-ktx", "navigation-ui-ktx"] }

使用上跟方式一完全一样,默认我们不需要在settings.gradle.kts配置任何东西。gradle会自动加载gradle目录下的libs.versions.toml文件,默认的名称也是libs。
当然,如果你想把文件名字或者路径改一下也完全没问题,改完后手动配置下依赖即可。

例如

  versionCatalogs {create("libs") {from(files("version-catalog/libs.versions.toml"))}}

发布到远端

如果你没有共享依赖的需求,那么上面的方式已经足够使用了。
但是现在基本上都是组件化开发了,特别是当组件数量比较多或者公司内有其他App时,大概率就会有统一依赖版本以及共享依赖的需求了。
那我们可以把Version Catalog发布到远端,组件或其他项目需要时直接依赖然后使用即可,这样就很方便的实现了版本的统一以及快速依赖了。毕竟拷贝来拷贝去非常麻烦且不好维护。

Version Catalog发布也比较简单,按照 官方文档 来即可。
发布完成后,直接依赖远程的配置就可以了。
示例:

    versionCatalogs {create("libs") {from("com.xeonyu:version-catalog:0.0.2-SNAPSHOT")}
}

到这里,我们就实现了共享版本目录了。

配合Include Build 简化配置

解决完共享依赖的问题后,我们还可以配合之前用的Include Build来简化日常的依赖配置。
比如作为一个module,它的配置比较固定,无非就是些 minSdk,targetSdk,混淆配置,插件配置之类的,而且每个module的配置基本一致,同时作为公司内部的组件,我们希望组件的版本(例如minSdk,targetSdk等)能够跟App的版本保持一致,那么我们就可以结合Include Build加上version catalog来实现了。
还有一些三方依赖比如room,therouter等,他们的配置是固定成套的,我们可以通过写插件的方式把他们的配置集中起来,项目需要用到时直接一行代码就能搞定依赖了。

示例:

plugins {alias(libs.plugins.yzq.android.application)alias(libs.plugins.yzq.android.room)
}

插件部分不是很通用,一般需要根据自身需要编码定制,这里就不啰嗦了,主要是提供些思路,抛砖引玉。
关于插件的发布可以参考
发布Gradle插件 文档,剩下的就是写插件发布然后应用了。

总结

总而言之,Version Catalog和Include Build可以帮助开发人员更好地管理和配置项目中的依赖库和插件,提高开发效率,并保持版本的统一性。同时,通过发布Version Catalog和编写Gradle插件,可以实现依赖的共享和集中管理。


如果你觉得本文对你有帮助,麻烦动动手指顶一下,可以帮助到更多的开发者,如果文中有什么错误的地方,还望指正,转载请注明转自喻志强的博客 ,谢谢!

这篇关于新一代版本依赖管理Vesion Catalog的探索与实践的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/585603

相关文章

Python一次性将指定版本所有包上传PyPI镜像解决方案

《Python一次性将指定版本所有包上传PyPI镜像解决方案》本文主要介绍了一个安全、完整、可离线部署的解决方案,用于一次性准备指定Python版本的所有包,然后导出到内网环境,感兴趣的小伙伴可以跟随... 目录为什么需要这个方案完整解决方案1. 项目目录结构2. 创建智能下载脚本3. 创建包清单生成脚本4

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

javacv依赖太大导致jar包也大的解决办法

《javacv依赖太大导致jar包也大的解决办法》随着项目的复杂度和依赖关系的增加,打包后的JAR包可能会变得很大,:本文主要介绍javacv依赖太大导致jar包也大的解决办法,文中通过代码介绍的... 目录前言1.检查依赖2.更改依赖3.检查副依赖总结 前言最近在写项目时,用到了Javacv里的获取视频

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

PHP应用中处理限流和API节流的最佳实践

《PHP应用中处理限流和API节流的最佳实践》限流和API节流对于确保Web应用程序的可靠性、安全性和可扩展性至关重要,本文将详细介绍PHP应用中处理限流和API节流的最佳实践,下面就来和小编一起学习... 目录限流的重要性在 php 中实施限流的最佳实践使用集中式存储进行状态管理(如 Redis)采用滑动

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

ShardingProxy读写分离之原理、配置与实践过程

《ShardingProxy读写分离之原理、配置与实践过程》ShardingProxy是ApacheShardingSphere的数据库中间件,通过三层架构实现读写分离,解决高并发场景下数据库性能瓶... 目录一、ShardingProxy技术定位与读写分离核心价值1.1 技术定位1.2 读写分离核心价值二

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

Spring 依赖注入与循环依赖总结

《Spring依赖注入与循环依赖总结》这篇文章给大家介绍Spring依赖注入与循环依赖总结篇,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. Spring 三级缓存解决循环依赖1. 创建UserService原始对象2. 将原始对象包装成工