Android Studio统一依赖管理Composing builds

Android Studio统一依赖管理

背景

在我们的AS项目中,经常引用多个Module,多人参与项目开发,这种背景下,我们会时常遇到版本冲突问题,出现不同的compileSdkVersion等,导致我们的包体变大,项目运行时间变长,所以将依赖版本统一是一个项目优化的必经之路。

你可能遇到这样的问题
在架构设计阶段,你的依赖库是这样的
在这里插入图片描述
同事并行开发后,合并代码后,变成了这样
在这里插入图片描述
哈哈哈,这就是没做好依赖管理的后果!下面介绍三种依赖管理方式。如果对前两种已经很熟悉了,可以直接跳转看第三种Composing builds,推荐使用第三种。

一、Groovy ext扩展函数的替代方式

我们在使用Groovy语言构建项目的时候,抽取config.gradle作为全局的变量控制,使用ext扩展函数来统一配置依赖,如下:
在这里插入图片描述
示例代码:

ext {
    android = [
            compileSdkVersion: 29,
            buildToolsVersion: "29",
            minSdkVersion    : 17,
            targetSdkVersion : 26,
            versionCode      : 102,
            versionName      : "1.0.2"
    ]

    version = [
            appcompatVersion       : "1.1.0",
            coreKtxVersion         : "1.2.0",
            supportLibraryVersion  : "28.0.0",
            androidTestVersion     : "3.0.1",
            junitVersion           : "4.12",
            glideVersion           : "4.11.0",
            okhttpVersion          : "3.11.0",
            retrofitVersion        : "2.3.0",
            constraintLayoutVersion: "1.1.3",
            gsonVersion            : "2.7",
            rxjavaVersion          : "2.2.2",
            rxandroidVersion       : "2.1.0",
            ..........省略...........
    ]

    dependencies = [
            //base
            "constraintLayout"      : "androidx.constraintlayout:constraintlayout:${version["constraintLayoutVersion"]}",
            "appcompat"             : "androidx.appcompat:appcompat:${version["appcompatVersion"]}",
            "coreKtx"               : "androidx.core:core-ktx:${version["coreKtxVersion"]}",
            "material"              : "com.google.android.material:material:1.2.1",

            //multidex
            "multidex"              : "com.android.support:multidex:${version["multidexVersion"]}",

            //okhttp
            "okhttp"                : "com.squareup.okhttp3:okhttp:${version["okhttpVersion"]}",
            "logging-interceptor"   : "com.squareup.okhttp3:logging-interceptor:${version["okhttpVersion"]}",

            //retrofit
            "retrofit"              : "com.squareup.retrofit2:retrofit:${version["retrofitVersion"]}",
            "converter-gson"        : "com.squareup.retrofit2:converter-gson:${version["retrofitVersion"]}",
            "adapter-rxjava2"       : "com.squareup.retrofit2:adapter-rxjava2:${version["retrofitVersion"]}",
            "converter-scalars"     : "com.squareup.retrofit2:converter-scalars:${version["retrofitVersion"]}",
			..........省略...........
    ]
}

依赖写完之后,在root路径下的build.gradle
添加apply from: "config.gradle"
在这里插入图片描述
然后在需要依赖的module下的build.gradle中

dependencies {
	...
    // Retrofit + okhttp 相关的依赖包
    api rootProject.ext.dependencies["retrofit"]
    ...
    }

以上就是Groovy ext扩展函数的依赖管理方式,此方式可以做到版本依赖,但是最大的缺点就是无法跟踪代码,想要找到上面示例代码中的rootProject.ext.dependencies["retrofit"]这个依赖,需要手动切到config.gradle去搜索查找,可读性很差。

二、使用buildSrc+kotlin的方式

buildSrc的方式,是最近几年特别流行的版本依赖管理方式。它有以下几个优点:

  • 支持双向跟踪
  • buildSrc是Android默认插件,全局只有这一个地方可以修改
  • 支持Android Studio的代码补全,以下演示示例图来自于网络

在这里插入图片描述
使用方式可参考:Kotlin + buildSrc for Better Gradle Dependency Management

缺点:buildSrc 依赖更新将重新构建整个项目,项目越大,重新构建的时间就越长,造成不必要的时间浪费。

三、Composing builds

Composing builds:A composite build is simply a build that includes other builds. In many ways a composite build is similar to a Gradle multi-project build, except that instead of including single projects, complete builds are included.(Composing builds只是包含其他构建的构建。 在许多方面,复合构建类似于Gradle多项目构建,不同之处在于,它包括完整的构建,而不是包括单个项目。)

使用这种方式的优点有:
1.支持单向跟踪
2.自动补全
3.依赖更新时,不会重新构建整个项目

使用方式
1.新建module,名为VersionPlugin(自起)
2.在新建的module下的build.gradle文件中,添加如下代码:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        // 因为使用的 Kotlin 需要需要添加 Kotlin 插件
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10"
    }
}

apply plugin: 'kotlin'
apply plugin: 'java-gradle-plugin'

repositories {
    // 需要添加 jcenter 否则会提示找不到 gradlePlugin
    jcenter()
    google()
}

dependencies {
    implementation gradleApi()
    implementation "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10"
}

compileKotlin {
    kotlinOptions {
        jvmTarget = "1.8"
    }
}
compileTestKotlin {
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

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

3.在 VersionPlugin/src/main/java/包名/ 目录下新建 DependencyManager.kt 文件,添加你的依赖配置,如:

package com.controler.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"
	...
}

4.在 VersionPlugin/src/main/java/包名/ 目录下新建 VersionPlugin.kt,
实现Plugin接口,如下:

package com.controler.versionplugin

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

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

    }

    companion object{
        
    }
}

注:新建VersionPlugin module时,生成的其他无用资源可以删去,只保留需要的,如下:
在这里插入图片描述
5.在 settings.gradle 文件内添加 includeBuild ("VersionPlugin")',注意是includeBuild 哦~,Rebuild项目
6.后面就可以在需要使用的gradle文件中使用了,如app下的build.gradle,在首行添加以下内容:

plugins {
    // 在第二部定义的插件ID
    id "com.controler.versionplugin"
}

// 定义的依赖地址
import com.controler.versionplugin.* 

使用如下
在这里插入图片描述
在这里插入图片描述

总结

1.使用groovy ext的方式,无法跟踪依赖关系,可读性差,不便维护
2.使用Kotlin + BuildSrc,支持双向跟踪,依赖更新时会重新构建整个项目
3.使用Composing builds,支持单向跟踪,依赖更新时不会构建整个项目

参考文献

Android ext
Kotlin + buildSrc for Better Gradle Dependency Management
Composing builds
拥抱 Composing builds 提升 Android 编译速度

猜你喜欢

转载自blog.csdn.net/Json_Jerry/article/details/112860914