Gradle统一管理依赖

背景

随着项目越来越大,module 越来越多,依赖的库也越来越多,依赖管理也越来越混乱。
我们一般会有以下需求:
1.  项目依赖统一管理,在单独文件中配置
2.  不同 Module 中的依赖版本号统一

管理 Gradle 依赖

说明:下面所有示例都是基于 Gradle 7.3.0 版本

一、原始粗暴式

在 module 的 build.gradle 中直接引入,就像下面代码一样

plugins {id 'com.android.application'id 'org.jetbrains.kotlin.android'
}android {compileSdk 33defaultConfig {applicationId "com.example.gradle"minSdk 21targetSdk 33versionCode 1versionName "1.0"testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}kotlinOptions {jvmTarget = '1.8'}
}dependencies {implementation 'androidx.core:core-ktx:1.9.0'implementation 'androidx.appcompat:appcompat:1.6.1'implementation 'com.google.android.material:material:1.6.1'implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
}

优点:方便快捷,依赖的时候复制粘贴一气呵成

缺点:多模块中可能会存在不同版本的依赖,进行版本升级的时候改动非常麻烦。

二、ext 式

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

1. 直接在 project 的 build.gradle 中编写 ext 。

ext {versions = [compileSdk      : 33,minSdk          : 21,targetSdk       : 33,versionCode     : 1,versionName     : "1.0.0",core_ktx        : "1.9.0",appcompat       : "1.6.1",material        : "1.6.1",constraintlayout: "2.1.4"]libraries = [core_ktx        : "androidx.core:core-ktx:${versions.core_ktx}",appcompat       : "androidx.appcompat:appcompat:${versions.appcompat}",material        : "com.google.android.material:material:${versions.material}",constraintlayout: "androidx.constraintlayout:constraintlayout:${versions.constraintlayout}"]
}

在 module 的 build.gradle 中的使用如下 

plugins {id 'com.android.application'id 'org.jetbrains.kotlin.android'
}android {compileSdk versions.compileSdkdefaultConfig {applicationId "com.example.gradle"minSdk versions.minSdktargetSdk versions.targetSdkversionCode versions.versionCodeversionName versions.versionNametestInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}kotlinOptions {jvmTarget = '1.8'}
}dependencies {implementation libraries.core_ktximplementation libraries.appcompatimplementation libraries.materialimplementation libraries.constraintlayout
}

这样,所有的 module 需要更新依赖库版本的时候,去修改 ext 下的代码即可

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

随着依赖项越来越多,ext 中的代码也越来越庞大,为了更好地管理。我们会把代码写在一个 .gradle ( config.gradle )文件中。

 config.gradle 中的代码如下

ext {versions = [compileSdk      : 33,minSdk          : 21,targetSdk       : 33,versionCode     : 1,versionName     : "1.0.0",core_ktx        : "1.9.0",appcompat       : "1.6.1",material        : "1.6.1",constraintlayout: "2.1.4"]libraries = [core_ktx        : "androidx.core:core-ktx:${versions.core_ktx}",appcompat       : "androidx.appcompat:appcompat:${versions.appcompat}",material        : "com.google.android.material:material:${versions.material}",constraintlayout: "androidx.constraintlayout:constraintlayout:${versions.constraintlayout}"]
}

在 project 的 build.gradle 中的中引用 config.gradle 文件,方式如下图:

在 module 的 build.gradle 中的使用不变

优点:依赖的版本统一管理,版本升级只用修改config.gradle 文件中的 ext 属性。

缺点: 在 module 的 build.gradle 中使用时,不支持代码提醒,不支持点击跳转,多 moudle 开发时,不同 module 的依赖需要 ctrl+c/v 导致开发的效率降低

三、kotlin+buildSrc式

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

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

  1. 在 project 的根目录下创建 buildSrc 目录

  2. 在 buildSrc 中新建 build.gradle 文件

    apply plugin: 'kotlin'buildscript {// 这里保持与主工程版本一致ext.kotlin_version = '1.7.20'repositories {mavenCentral()google()}dependencies {classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"}
    }repositories {mavenCentral()google()
    }
  3. 在 buildSrc 中创建 /src/main/kotlin目录,然后在新建 com.gradle 包名,最后创建 Dependencies.kt 文件

     4. Dependencies.kt 中编写依赖管理的代码,如下

object Versions {const val compileSdk = 33const val minSdk = 21const val targetSdk = 33const val versionCode = 1const val versionName = "1.0.0"const val core_ktx = "1.9.0"const val appcompat = "1.6.1"const val material = "1.6.1"const val constraintlayout = "2.1.4"
}object Libraries {const val core_ktx = "androidx.core:core-ktx:${Versions.core_ktx}"const val appcompat = "androidx.appcompat:appcompat:${Versions.appcompat}"const val material = "com.google.android.material:material:${Versions.material}"const val constraintlayout = "androidx.constraintlayout:constraintlayout:${Versions.constraintlayout}"
}

     5. 在 module 的 build.gradle 中使用如下 

import com.gradle.Libraries
import com.gradle.Versionsplugins {id 'com.android.application'id 'org.jetbrains.kotlin.android'
}android {compileSdk Versions.compileSdkdefaultConfig {applicationId "com.example.gradle"minSdk Versions.minSdktargetSdk Versions.targetSdkversionCode Versions.versionCodeversionName Versions.versionNametestInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}kotlinOptions {jvmTarget = '1.8'}
}dependencies {implementation Libraries.core_ktximplementation Libraries.appcompatimplementation Libraries.materialimplementation Libraries.constraintlayout
}

 使用时 Android Stuido 自动提示如下

优点:这种方式支持 IDE 输入代码会有提示,会自动完成,并且支持 AndroidStudio 单击跳转。

缺点:依赖更新将重新构建整个项目,对编译速度有一定的影响。而且 buildSrc 是编译期才生效,并且其生命周期在project 的 build.gadle 执行之后,所以没办法把插件相关的配置给维护起来。

四、Verison Catalogs 管理

4.1 Version Catalogs 特点

  • 对所有 module 可见,可统一管理所有 module 的依赖,Gradle 会为每个依赖目录生成一个类型安全的访问器,同时可以管理 project 的 build.gradle 中的插件依赖。

  • 依赖项除了可以声明为单个依赖目录,还可以将多个依赖项声明为依赖目录组。即支持声明依赖bundles, 即总是一起使用的依赖可以组合在一起,

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

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

  • 支持在项目间共享依赖

4.2 启用 Version Catalogs

在 AGP 低版本中, Version Catalogs 属于孵化中的特效,使用它之前需要启用该特性。

在 settings.gradle 中添加如下代码:

pluginManagement {...
}enableFeaturePreview("VERSION_CATALOGS")dependencyResolutionManagement {...
}...

4.3 使用 Version Catalogs

在 settings.gradle 中声明,如下:

...
dependencyResolutionManagement {...// 编写版本目录的依赖库versionCatalogs {libs {// 版本version('compileSdk', '33')version('minSdk', '21')version('targetSdk', '33')version('versionCode', '1')version('versionName', '1.0.0')/*** 声明依赖* 例如:别名('coreKtx')、groupId('androidx.core')、artifactId('core-ktx')以及版本('1.9.0')* alias 在AGP的低版本中使用,高版本中使用 library*/// alias('coreKtx').to('androidx.core', 'core-ktx').version('1.9.0')library('coreKtx', 'androidx.core', 'core-ktx').version('1.9.0')library('appcompat', 'androidx.appcompat', 'appcompat').version('1.6.1')library('material', 'com.google.android.material', 'material').version('1.6.1')library('constraintlayout', 'androidx.constraintlayout', 'constraintlayout').version('2.1.4')// 除了单个依赖声明,我们也可以将多个依赖项声明为一个依赖组bundle('appBaseLib', ['coreKtx', 'appcompat', 'material', 'constraintlayout'])// 针对多个相同版本号的依赖,我们可以定一个通用版本号,即将依赖与版本单独声明并引用version('lifecycle', '2.2.0')library('lifecycleExtensions', 'androidx.lifecycle', 'lifecycle-extensions').versionRef('lifecycle')library('lifecycleRuntimeKtx', 'androidx.lifecycle', 'lifecycle-runtime-ktx').versionRef('lifecycle')/*** 声明插件(在高版本的AGP中才有)*/plugin('androidApplication', 'com.android.application').version('7.3.0')plugin('kotlinAndroid', 'org.jetbrains.kotlin.android').version('1.7.20')}}
}...

在 project 的 build.gradle 中的使用如下

plugins {
//    id 'com.android.application' version '7.3.0' apply false
//    id 'org.jetbrains.kotlin.android' version '1.7.20' apply false/* 依赖插件 等同于上面注释掉的代码 */alias(libs.plugins.androidApplication) apply falsealias(libs.plugins.kotlinAndroid) apply false
}

在 module 的 build.gradle 中的使用如下

plugins {
//    id 'com.android.application'
//    id 'org.jetbrains.kotlin.android'/* 依赖插件 等同于上面注释掉的代码 */alias(libs.plugins.androidApplication)alias(libs.plugins.kotlinAndroid)
}android {compileSdk libs.versions.compileSdk.get().toInteger()defaultConfig {applicationId "com.example.gradle"minSdk libs.versions.minSdk.get().toInteger()targetSdk libs.versions.targetSdk.get().toInteger()versionCode libs.versions.versionCode.get().toInteger()versionName libs.versions.versionName.get()testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}kotlinOptions {jvmTarget = '1.8'}
}dependencies {// 依赖单个指定的版本
//    implementation libs.coreKtx
//    implementation libs.appcompat
//    implementation libs.material
//    implementation libs.constraintlayout// 依赖项包implementation libs.bundles.appBaseLibimplementation libs.lifecycleExtensionsimplementation libs.lifecycleRuntimeKtx}

这种方式支持 IDE 输入代码会有提示,会自动完成,并且支持 AndroidStudio 单击跳转。但是这种方式会导致 settings.gradle 非常臃肿

通过 toml 文件声明 version catalogs

除了在 settings.gradle 文件中直接声明依赖目录,官方更推荐使用 toml 文件来声明依赖目录,而且在 toml 中编写代码时 Android Studio 会有提示,非常的方便。

首先在项目根目录下创建 libs.versions.toml 文件,文件名可以任意取,并编写如下依赖内容:

[versions]
agp = "7.3.0"
kotlin = "1.7.20"
compileSdk = "33"
minSdk = "21"
targetSdk = "33"
versionCode = "1"
versionName = "1.0.0"coreKtx = "1.9.0"
appcompat = "1.6.1"
material = "1.6.1"
constraintlayout = "2.1.4"
lifecycle = "2.2.0"[libraries]
coreKtx = { module = "androidx.core:core-ktx", version.ref = "coreKtx" }
appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat" }
material = { module = "com.google.android.material:material", version.ref = "material" }
constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "constraintlayout" }
lifecycleExtensions = { module = "androidx.lifecycle:lifecycle-extensions", version.ref = "lifecycle" }
lifecycleRuntimeKtx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycle" }[bundles]
appBaseLib = ["coreKtx", "appcompat", "material", "constraintlayout"][plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" }
kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }

toml 文件的使用说明

1. toml 文件由 4个主要部分组成

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

[libraries] 用于声明依赖的别名

[bundles] 用于声明依赖包(依赖组)

[plugins] 用于声明插件(AGP低版本不支持)

2. 声明 libraries 时,可以使用

coreKtx = { module = "androidx.core:core-ktx", version.ref = "coreKtx" }

或者

coreKtx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }

随后在 setting.gradle 中引用该 toml 文件

...
dependencyResolutionManagement {...// 编写版本目录的依赖库versionCatalogs {libs {from(files("./libs.versions.toml"))}}
}...

在 module 的 build.gradle 中的使用方式不变。

注意:Version Catalogs 中变量命名大小写敏感,且以小写字母开头, 命名中可以如包含 “-” 或者 “_” 或者 “.” ,在相当于分组了。

举例说明:

lifecycle_runtime_ktx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycle" }

在使用时

implementation libs.lifecycle.runtime.ktx

4.4 发布到远端

如果你没有共享依赖的需求,那么上面的方式已经足够使用了。

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

Version Catalog发布也比较简单,按照 官方文档 来即可。

总结

Android 发展至今,各种新技术层出不穷,版本管理也出现了很多方案,这些方案并没有绝对的优劣,还是需要结合实际项目需求来选择的,但是新的方案还是需要学习了解的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/260888.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【动态规划专栏】专题二:路径问题--------6.地下城游戏

本专栏内容为:算法学习专栏,分为优选算法专栏,贪心算法专栏,动态规划专栏以及递归,搜索与回溯算法专栏四部分。 通过本专栏的深入学习,你可以了解并掌握算法。 💓博主csdn个人主页:小…

区块链游戏解说:什么是 Nine Chronicles

作者:lesleyfootprint.network 编译:cicifootprint.network 数据源: Nine Chronicles Dashboard 什么是 Nine Chronicles Nine Chronicles 是一款去中心化的在线角色扮演游戏,标志着在线游戏和区块链技术的发展。 Nine Chroni…

IMS audio codec的优先级

IMS voice call过程中&#xff0c;UE端的 audio codec也是有优先级规定的&#xff0c;具体规定如下。 如RFC 4566或8866 SDP 协议中的描述&#xff0c;如果<proto>是“RTP/AVP”或“RTP/SAVP”&#xff0c;则<fmt>会包含RTP paylaod type。 当给出paylaod type nu…

第2.4章 StarRocks表设计——分区分桶与副本数

目录 一、数据分布 1.1 概述 1.2 数据分布方式 1.2.1 Round-Robin 1.2.2 Range 1.2.3 List 1.2.4 Hash 1.3 StarRocks的数据分布方式 1.3.1 不分区 Hash分桶 1.3.2 Range分区Hash分桶 三、分区 3.1 分区概述 3.2 创建分区 3.2.1 手动创建分区 3.2.2 批量创建分区…

单片机学习笔记---红外遥控红外遥控电机调速(完结篇)

目录 低电平触发中断和下降沿触发中断的区别 红外遥控 Int0.c Int.h Timer0.c Timer0.h IR.c IR.h main.c 红外遥控电机调速 Timer1.c Timer.h Motor.c Motor.h main.c 上一节讲了红外发送和接收的工作原理&#xff0c;这一节开始代码演示&#xff01; 提前说…

Linux-ls命令

目录 ls&#xff1a;查看目录下文件/文件夹 ls -l&#xff1a;列表显示文件 ls -a&#xff1a;显示所有文件正常情况下‘ . ’开头的文件是隐藏的 ls -la&#xff1a;以列表形式显示所有文件包括隐藏文件 ls -lt&#xff1a;按时间倒序查看文件 ls -R&#xff1a;递归方式…

基于JavaWeb实现的在线蛋糕商城

一、系统架构 前端&#xff1a;jsp | bootstrap | js | css 后端&#xff1a;servlet | mybatis 环境&#xff1a;jdk1.7 | mysql | maven | tomcat 二、代码及数据库 三、功能介绍 01. web页-首页 02. web页-商品分类 03. web页-热销 04. web页-新品 05. w…

dockerfile文件书写

1.dockerfile构建nginx镜像 1.1书写dockerfile文件 mkdir nginx #创建nginx目录 cd nginx vim dockerfile # 修改文件FROM centos # 基础镜像&#xff0c;默认最新的centos8操作系统 MAINTAINER xianchao # 指定镜像的作者信息 RUN rm -rf /etc/yum.repos.d/* # centos8默认…

MongoDB 权限管理

文章目录 前言1. 权限控制1.1 MongoDB 默认角色1.1.1 读写角色1.1.2 管理角色1.1.3 其他角色1.1.4 超级用户角色 1.2 用户管理1.2.1 查看用户1.2.2 创建新用户1.2.3 调整角色1.2.4 删除用户1.2.4 修改密码 前言 上一篇 《MongoDB 单机安装部署》 文章中&#xff0c;为 MongoDB…

【HarmonyOS应用开发】三方库(二十)

三方库的基本使用 一、如何获取三方库 目前提供了两种途径获取开源三方库&#xff1a; 通过访问Gitee网站开源社区获取 在Gitee中&#xff0c;搜索OpenHarmony-TPC仓库&#xff0c;在tpc_resource中对三方库进行了资源汇总&#xff0c;可以供开发者参考。 通过OpenHarmony三…

自然语言编程系列(二):自然语言处理(NLP)、编程语言处理(PPL)和GitHub Copilot X

编程语言处理的核心是计算机如何理解和执行预定义的人工语言&#xff08;编程语言&#xff09;&#xff0c;而自然语言处理则是研究如何使计算机理解并生成非正式、多样化的自然语言。GPT-4.0作为自然语言处理技术的最新迭代&#xff0c;其编程语言处理能力相较于前代模型有了显…

QEMU源码全解析 —— virtio(20)

接前一篇文章&#xff1a; 上回书重点解析了virtio_pci_modern_probe函数。再来回顾一下其中相关的数据结构&#xff1a; struct virtio_pci_device struct virtio_pci_device的定义在Linux内核源码/drivers/virtio/virtio_pci_common.h中&#xff0c;如下&#xff1a; /* O…

智慧驿站_智慧文旅驿站_轻松的驿站智慧公厕_5G智慧公厕驿站_5G模块化智慧公厕

多功能城市智慧驿站是在智慧城市建设背景下&#xff0c;所涌现的一种创新型社会配套设施。其中&#xff0c;智慧公厕作为城市智慧驿站的重要功能基础&#xff0c;具备社会配套不可缺少的特点&#xff0c;所以在应用场景上&#xff0c;拥有广泛的需求和要求。那么&#xff0c;城…

springcloud-网关(gateway)

springcloud-网关(gateway) 概述 \Spring Cloud Gateway旨在提供一种简单而有效的方式来路由到API&#xff0c;并为其提供跨领域的关注&#xff0c;如&#xff1a;安全、监控/指标和容错 常用术语 Route&#xff08;路由&#xff09;: 网关的基本构件。它由一个ID、一个目的地…

【ArcGIS微课1000例】0103:导出点、线、面要素的折点坐标值

点要素对应的是一个或者若干个坐标,线要素对应的是对个坐标值对应的点连起来,面要素是多个坐标值对应的点连起来构成的封闭多边形。本文讲述导出点的坐标值。 文章目录 一、点要素坐标导出1. 计算点坐标2. 导出点坐标二、线要素坐标导出1. 生成线要素折点2. 计算折点坐标3. 导…

【打工日常】使用docker部署Dashdot工具箱

一、Dashdot介绍 dashdot是一个简洁清晰的服务器数据仪表板&#xff0c;基于React实现 &#xff0c;主要是显示操作系统、进程、存储、内存、网络这五个的数据。 二、本次实践介绍 1. 本次实践简介 本次实践部署环境为个人测试环境 2. 本地环境规划 本次实践环境规划&#xf…

S-35390A开发

计时芯片 S-35390A芯片是计时芯片&#xff0c;一般用来计算时间。低功耗&#xff0c;宽电压&#xff0c;受温度影响小&#xff0c;适用于很多电路。它有一个问题&#xff0c;不阻止用户设置不存在的时间&#xff0c;设置进去之后计时或者闹钟定时会出错。 规格书阅读 首先我…

成为大佬之路--linux软件安装使用第000000003篇--vmare安装centos

准备工作 1.下载centos安装包 2.安装vmare 建议直接百度 绿色版 直接上最新版本旗舰版(pro) 新建虚拟机 1.打开vamre,点击文件--新建虚拟机 2.直接默认选择 "典型",点击下一步 3. 选择稍后安装操作系统,点击下一步 4.选择linux版本 因为安装的是centos直接选…

Arcmap excel转shp

使用excel表格转shp的时候&#xff0c;如果你的excel里面有很多字段&#xff0c;直接转很大概率会出现转换结果错误的情况&#xff0c;那么就需要精简一下字段的个数。将原来的表格文件另存一份&#xff0c;在另存为的文件中只保留关键的经度、纬度、和用于匹配的字段即可&…

【C++】C++11下线程库

C11下线程库 1. thread类的简单介绍2.线程函数参数3.原子性操作库(atomic)4.mutex的种类5. RAII风格加锁解锁5.1Lock_guard5.2unique_lock 6.condition_variable 1. thread类的简单介绍 在C11之前&#xff0c;涉及到多线程问题&#xff0c;都是和平台相关的&#xff0c;比如wi…