一般对项目的依赖管理会有以下需求。
1、项目依赖同意管理,在单独文件中配置。
2、不同的Module种的依赖版本号统一
3、不同项目种的依赖版本号统一
针对这些需求,提出了以下集中方案:
1、使用循环优化Gradle依赖管理
2、使用buildSrc管理Gradle依赖
3、使用includeBuild统一配置依赖版本
4、使用Version Catalog统一配置依赖版本。
使用循环优化Gradle依赖管理
这种方式就是在app的目录下创建一个xxx.gradle文件,然后将我们项目所有需要用到的依赖放到该文件里,并分好类,例如:
ext{
android = [
compileSdkVersion : 29,
buildToolsVersion : "29.0.3",
minSdkVersion : 21,
targetSdkVersion : 29,
versionCode : 10101,
versionName : "1.01.01"
]
dependencies = [
"rxlifecycle" : "com.trello.rxlifecycle2:rxlifecycle:2.2.2",
"rxlifecycle-android" : "com.trello.rxlifecycle2:rxlifecycle-android:2.2.2",
"rxlifecycle-components" : "com.trello.rxlifecycle2:rxlifecycle-components:2.2.2",
//网络
"retrofit" : "com.squareup.retrofit2:retrofit:2.6.2",
"retrofit_adapter" : "com.squareup.retrofit2:adapter-rxjava2:2.6.2",
"retrofit_gson" : "com.squareup.retrofit2:converter-gson:2.6.2",
"rxjava" : "io.reactivex.rxjava2:rxjava:2.2.14",
"rx_android" : "io.reactivex.rxjava2:rxandroid:2.1.1",
//gson
........
]
annotationProcessor = [
"butterknife-compiler" :"com.jakewharton:butterknife-compiler:10.0.0",
"glide-compiler" : "com.github.bumptech.glide:compiler:4.9.0",
"dagger-compiler" : "com.google.dagger:dagger-compiler:2.24",
]
apiFileDependencies = [
"launchstarter" :"libs/launchstarter-release-1.0.0.aar"
]
debugImplementationDependencies = [
"MethodTraceMan" : "com.github.zhengcx:MethodTraceMan:1.0.7"
]
...
implementationExcludes = [
"com.android.support.test.espresso:espresso-idling-resource:3.0.2" : [
'com.android.support' : 'support-annotations'
]
]
然后在我们的build.gradle文件中引用该文件
apply from:"config.gradle"
最后在build.gradle的dependencies中添加如下代码:
def implementationDependencies = project.ext.dependencies
def processors = project.ext.annotationProcesso
def implementationExcludes = project.ext.implementationExcludes
dependencies{
// 处理所有的 xxximplementation 依赖
implementationDependencies.each { k, v -> implementation v }
// 处理 annotationProcessor 依赖
processors.each { k, v -> annotationProcessor v }
// 处理所有包含 exclude 的依赖
implementationExcludes.each { entry ->
implementation(entry.key) {
entry.value.each { childEntry ->
exclude(group: childEntry)
}
}
}
这样做的优点在于
1.后续添加依赖不需要改动build.gradle,直接在config.gradle中添加即可
2.精简了build.gradle的长度
但是还是有一些痛点:
1.不支持代码提示
2.不支持单击跳转
3.多模块开发时,不同模块相同的依赖需要复制粘贴。
使用buildSrc管理Gradle依赖
创建一个名为buildSrc的module.因为运行Gradle时,它会检查项目中是否存在一个名为buildSrc的目录。然后Gradle会自动编译并测试这段代码,并将其放入构建脚本的类路径中。您不需要提供任何进一步的操作提示。 所以也不需要在settings.gradle文件中添加include xxx。
步骤如下:
1.新建文件 build.gradle.kts,并同步 gradle
plugins {
`kotlin-dsl`
}
repositories {
jcenter()
}
2.创建 /src/main/java/Version.kt 文件,在 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}"
}
3.在 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
}
缺点:由于 buildSrc 是对全局的所有 module 的配置,因此在构建速度上会慢一些。
使用includeBuild统一配置依赖版本
步骤如下:
1.先创建一个java或kotlin的library.
2.然后在创建好的library的build.gradle文件中添加以下代码,我这里用的kotlin,如果用的Java,则 apply plugin: 'java-library'。
apply plugin: 'kotlin'
apply plugin: 'java-gradle-plugin'
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10"
}
}
repositories {
jcenter()
google()
}
dependencies {
implementation gradleApi()
implementation "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10"
}
gradlePlugin{
plugins{
version{
//id 对应package name
id = "com.example.version"
//implementationClass 则是对应我们第三步需要创建的一个类,其内容为包名 + 类名
implementationClass = "com.example.version.DependencyVersionPlugin"
}
}
}
3.在com.example.version路径下创建一个类
class DependencyVersionPlugin : Plugin {
override fun apply(target: Project) {
}
}
4.在src/main/java的路径下添加文件,文件里就是所有的依赖集合
5.在settings.gradle添加
//括号里对应library名
includeBuild("version")
6.然后在需要的module,添加
plugins{
id "com.example.version"
}
sync之后,就可使用了。
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation(AndroidX.coreKtx)
implementation(AndroidX.appcompat)
implementation(AndroidX.constraintlayout)
}
这里有一个坑,不能将
android {
compileSdkVersion ProjectBuildConfigs.compileSdkVersion
buildToolsVersion ProjectBuildConfigs.buildToolsVersion
defaultConfig {
minSdkVersion ProjectBuildConfigs.minSdkVersion
targetSdkVersion ProjectBuildConfigs.targetSdkVersion
versionCode ProjectBuildConfigs.versionCode
versionName ProjectBuildConfigs.versionName
consumerProguardFiles "consumer-rules.pro"
ndk {
// 设置支持的SO库架构
//abiFilters 'armeabi', 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a'
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86'
}
}
}
这些公共的东西放在一个公共的base_xxx.gradle,然后再在build.gradle里面 apply from "base_xxx.gradle ",这样会一直报compileSdkVersion is not specified.的错误。我在这上面弄了好久,一直怀疑是写的有问题。
使用红色框的方式会一直报错,所以我们需要采用绿色框的方式
还有一个坑就是不能套娃:
object Kotlin {
const val Kotlin = "org.jetbrains.kotlin:kotlin-stdlib:${Version.Kotlin}"
const val CoroutinesCore =
"org.jetbrains.kotlinx:kotlinx-coroutines-core:${Version.Coroutines}"
const val CoroutinesAndroid =
"org.jetbrains.kotlinx:kotlinx-coroutines-android:${Version.Coroutines}"
object GitHub {
const val OkHttp = "com.squareup.okhttp3:okhttp:${Version.OkHttp}"
const val OkHttpInterceptorLogging =
"com.squareup.okhttp3:logging-interceptor:${Version.OkHttpInterceptorLogging}"
const val Retrofit = "com.squareup.retrofit2:retrofit:${Version.Retrofit}"
}
}
这样会编译不过。
使用Version Catalog统一配置依赖版本
Catalog 是Gradle7.0推出了一个新的特性,它支持以下特性:
1.对所有module可见,可统一管理所有module的依赖
2.支持声明依赖bundles,即总是一起使用的依赖可以组合在一起
3.支持版本号与依赖名分离,可以在多个依赖间共享版本号
4.支持在单独的libs.versions.toml文件中配置依赖
5.支持在项目间共享依赖
具体使用请看【Gradle7.0】依赖统一管理的全新方式,了解一下~
参考资料
【Gradle7.0】依赖统一管理的全新方式,了解一下~
git https://github.com/fengyuehan/Test/tree/master/version