<版本>Android统一依赖管理

语言: CN / TW / HK

theme: fancy

总结:

在多module的项目中,对版本的统一管理很重要,可以避免多个版本库的冲突问题,也方便日后的统一升级等等

Android的版本依赖的统一管理,有三种方式: - 传统apply from的方式 - buildsrc方式 - composing builds方式

一、传统apply from的方式

在根目录新建一个config.gradle(或其他随意的xxx.gradle)文件 或在根目录的build.gradle定义一些变量 如: ``` ext { android = [ compileSdkVersion: 30, buildToolsVersion: "30", minSdkVersion : 16, targetSdkVersion : 28, versionCode : 100, versionName : "1.0.0" ]

versions = [
        appcompatVersion       : "1.1.0",
        coreKtxVersion         : "1.2.0",
        supportLibraryVersion  : "28.0.0",
        glideVersion           : "4.11.0",
        okhttpVersion          : "3.11.0",
        retrofitVersion        : "2.3.0",
        constraintLayoutVersion: "1.1.3",
        gsonVersion            : "2.8",
        //等等······
]

dependencies = [
        //base
        "constraintLayout"      : "androidx.constraintlayout:constraintlayout:${version["constraintLayoutVersion"]}",
        "appcompat"             : "androidx.appcompat:appcompat:${version["appcompatVersion"]}",
        "coreKtx"               : "androidx.core:core-ktx:${version["coreKtxVersion"]}",
        //等等······
]

}

```

在工程的根目录build.gradle添加:

apply from"config.gradle"

在需要依赖的modulebuild.gradle中,依赖的方式如下: dependencies { ... // 添加appcompatVersion依赖 api rootProject.ext.dependencies["appcompatVersion"] ... }

【缺点】 - 无法跟踪代码,需要手动搜索相关的依赖 - 可读性很差

二、buildsrc方式

什么是buildsrc

当运行 gradle 时会检查项目中是否存在一个名为 buildsrc 的目录。然后 gradle 会自动编译并测试这段代码,并将其放入构建脚本的类路径中。

对于多项目构建,只能有一个 buildsrc 目录,该目录必须位于根项目目录中, buildsrc 是 gradle 项目根目录下的一个目录,它可以包含我们的构建逻辑。

与脚本插件相比,buildsrc 应该是首选,因为它更易于维护、重构和测试代码。

优缺点:

1】优点: - buildSrc是Android默认插件,共享 buildsrc 库工件的引用,全局只有这一个地方可以修改它 - 支持自动补全,支持跳转。 2】缺点: - 依赖更新将重新构建整个项目,项目越大,重新构建的时间就越长,造成不必要的时间浪费。 Gradle 文档

A change in buildSrc causes the whole project to become out-of-date. Thus, when making small incremental changes, the --no-rebuild command-line option is often helpful to get faster feedback. Remember to run a full build regularly or at least when you’re done, though.

buildSrc的更改会导致整个项目过时,因此,在进行小的增量更改时,-- --no-rebuild命令行选项通常有助于获得更快的反馈。不过,请记住要定期或至少在完成后运行完整版本。

使用方式:

参考:Kotlin + buildSrc for Better Gradle Dependency Management

  • 在项目根目录下新建一个名为 buildSrc 的文件夹(名字必须是 buildSrc,因为运行 Gradle 时会检查项目中是否存在一个名为 buildSrc 的目录)

  • 在 buildSrc 文件夹里创建名为 build.gradle.kts 的文件,添加以下内容 plugins { `kotlin-dsl` } repositories{ jcenter() }

  • 在 buildSrc/src/main/java/包名/ 目录下新建 Deps.kt 文件,添加以下内容 ``` object Versions { ......

    val appcompat = "1.1.0"

    ...... }

object Deps { ......

val appcompat =  "androidx.appcompat:appcompat:${Versions.appcompat}"

......

} ```

  • 重启 Android Studio,项目里就会多出一个名为 buildSrc 的 module,实现效果

示意图

三、composing builds方式

摘自 Gradle 文档:复合构建只是包含其他构建的构建. 在许多方面,复合构建类似于 Gradle 多项目构建,不同之处在于,它包括完整的 builds ,而不是包含单个 projects

  • 组合通常独立开发的构建,例如,在应用程序使用的库中尝试错误修复时
  • 将大型的多项目构建分解为更小,更孤立的块,可以根据需要独立或一起工作

优缺点:

1】优点: - 支持单向跟踪 - 自动补全 - 依赖更新时,不会重新构建整个项目

2】缺点: - 需要在每一个module中都添加相应的插件引用

使用方式:

参考Gradle文档

  • 新建的 module 名称 VersionPlugin(名字随意)
  • 在 versionPlugin 文件夹下的 build.gradle 文件内,添加以下内容 ``` buildscript { repositories { jcenter() } dependencies { // 因为使用的 Kotlin 需要需要添加 Kotlin 插件 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10" } }

apply plugin: 'kotlin' apply plugin: 'java-gradle-plugin' repositories { // 需要添加 jcenter 否则会提示找不到 gradlePlugin jcenter() }

gradlePlugin { plugins { version { // 在 app 模块需要通过 id 引用这个插件 id = 'com.yu.plugin' // 实现这个插件的类的路径 implementationClass = 'com.yu.versionplugin.VersionPlugin' } } } ```

  • 在 VersionPlugin/src/main/java/包名/ 目录下新建 DependencyManager.kt 文件,添加相关的依赖配置,如: ``` package com.yu.versionplugin

/* * 配置和 build相关的 / object BuildVersion { const val compileSdkVersion = 29 const val buildToolsVersion = "29.0.2" const val minSdkVersion = 17 const val targetSdkVersion = 26 const val versionCode = 102 const val versionName = "1.0.2" }

/* * 项目相关配置 / object BuildConfig { //AndroidX const val appcompat = "androidx.appcompat:appcompat:1.2.0" const val constraintLayout = "androidx.constraintlayout:constraintlayout:2.0.4" const val coreKtx = "androidx.core:core-ktx:1.3.2" const val material = "com.google.android.material:material:1.2.1" const val junittest = "androidx.test.ext:junit:1.1.2" const val swiperefreshlayout = "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" const val recyclerview = "androidx.recyclerview:recyclerview:1.1.0" const val cardview = "androidx.cardview:cardview:1.0.0"

//Depend
const val junit = "junit:junit:4.12"
const val espresso_core = "com.android.support.test.espresso:espresso-core:3.0.2"
const val guava = "com.google.guava:guava:24.1-jre"
const val commons = "org.apache.commons:commons-lang3:3.6"
const val zxing = "com.google.zxing:core:3.3.2"

//leakcanary
const val leakcanary = "com.squareup.leakcanary:leakcanary-android:2.4"

//jetPack
const val room_runtime = "androidx.room:room-runtime:2.2.5"
const val room_compiler = "androidx.room:room-compiler:2.2.5"
const val room_rxjava2 = "androidx.room:room-rxjava2:2.2.5"
const val lifecycle_extensions = "android.arch.lifecycle:extensions:1.1.1"
const val lifecycle_compiler = "android.arch.lifecycle:compiler:1.1.1"
const val rxlifecycle = "com.trello.rxlifecycle3:rxlifecycle:3.1.0"
const val rxlifecycle_components = "com.trello.rxlifecycle3:rxlifecycle-components:3.1.0"

//Kotlin
const val kotlinx_coroutines_core = "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7"
//...

} - 在 `VersionPlugin/src/main/java/包名/` 目录下新建 `VersionPlugin.kt`,实现Plugin接口,如下: package com.yu.versionplugin

import org.gradle.api.Plugin import org.gradle.api.Project

class VersionPlugin : Plugin{ override fun apply(p0: Project) {

}

companion object{

}

} ```

项目目录结构

  • settings.gradle 文件内添加如下代码,并重启 Android Studio //注意是 includeBuild includeBuild 'VersionPlugin'
  • app 模块 build.gradle 文件内 首行 添加以下内容

plugins{ // 这个 id 就是在 VersionPlugin 文件夹下 build.gradle 文件内定义的 id id "com.yu.plugin" } // 定义的依赖地址 import com.yu.versionplugin.*

  • 使用如下: ``` import com.yu.versionplugin.*

plugins { id 'com.android.application' id 'kotlin-android' id 'com.yu.plugin' }

android { compileSdk 32

defaultConfig {
    applicationId "com.yu.versiontest"
    minSdk BuildVersion.minSdkVersion
    targetSdk BuildVersion.targetSdkVersion
    versionCode BuildVersion.versionCode
    versionName BuildVersion.versionName
}
//.....

}

dependencies {

implementation BuildConfig.coreKtx
implementation BuildConfig.appcompat
implementation BuildConfig.material
//......

} ```

参考链接: