依赖版本管理的几种方式

讲下如何管理依赖版本,以及如何管理正式环境与测试环境的变量,最后讲下如何封装并控制依赖版本。

管理版本的方式不止我列出的几种,我只是写出了个人认为比较方便的方法。也是自用的方法,仅供各位高工参考。如有不正还请指出!

一. 使用gradle文件管理如dependent.gradle

dependent.gradle中定义一些依赖库的版本,然后在项目的跟build.gradle中引入,这样全部模块都可以使用到dependent.gradle中的值。
dependent.gradle:

ext {
    deps = [
            //android和kt依赖资源
            android: [
                    "appcompat"             : "androidx.appcompat:appcompat:1.3.1",
                    "design"                : "com.google.android.material:material:1.4.0",
                    "constraint_layout"     : "androidx.constraintlayout:constraintlayout:2.0.3",
                    "recyclerview"          : "androidx.recyclerview:recyclerview:1.2.0",
                    'fragment_ktx'          : 'androidx.fragment:fragment-ktx:1.3.6',
                    'multidex'              : 'androidx.multidex:multidex:2.0.1',

                    "kt_ktx"                : 'androidx.core:core-ktx:1.6.0',
                    "ktx_coroutines_core"   : 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2',
                    "ktx_coroutines_android": 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2',

                    "lifecycle"             : 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1',
                    "lifecycle_ktx"         : 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1',

                    "junit"                 : 'junit:junit:4.12',
                    "test_junit"            : 'androidx.test.ext:junit:1.1.1',
                    "test_espresso"         : 'androidx.test.espresso:espresso-core:3.2.0',

            ],

            //第三方
            support: [
                    "glide"             : 'com.github.bumptech.glide:glide:4.12.0',
                    "glide_annotation"  : 'com.github.bumptech.glide:annotations:4.12.0',
                    "glide_integration" : 'com.github.bumptech.glide:okhttp3-integration:4.12.0',
                    "glide_compiler"    : 'com.github.bumptech.glide:compiler:4.12.0',

                    "gif_drawable"      : 'pl.droidsonroids.gif:android-gif-drawable:1.2.10',

                    "hilt"              : 'com.google.dagger:hilt-android:2.38.1',
                    "hilt_kapt"         : 'com.google.dagger:hilt-android-compiler:2.38.1',

                    "arouter"           : 'com.alibaba:arouter-api:1.5.2',
                    "arouter_kapt"      : 'com.alibaba:arouter-compiler:1.5.2',

                    "retrofit2"         : 'com.squareup.retrofit2:retrofit:2.9.0',
                    "retrofit_gson"     : 'com.squareup.retrofit2:converter-gson:2.9.0',
                    'gson_factory'      : 'com.github.getActivity:GsonFactory:5.2',  //Gson转换容错处理
                  
                    ...

            ]

    ]

    versions = [
            'minSdk'    : 21,
            'targetSdk' : 31,
            'compileSdk': 31,
    ]

}
复制代码

build.gradle:

//直接引用
apply from: "dependent.gradle"
apply from: "config.gradle"
...
复制代码

在Lib库中就能直接使用了,如下:

apply from: "../lib_default_config.gradle"
apply plugin: 'dagger.hilt.android.plugin'

dependencies {

    //noinspection GradleDependency
    api "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"

    //路由
    api project(':cs_router')

    //AndroidX
    api deps.android.appcompat
    api deps.android.constraint_layout
    api deps.android.recyclerview
    api deps.android.design
    api deps.android.multidex
    ...
复制代码

二. 使用java-gradle-plugin插件的方式管理

这一种方法,使用插件的方式,可以在依赖的地方跳转到指定的位置,并且由于不是在gradle文件中修改的,所以修改值之后可以不需要build。

代码如上,需要在项目中创建一个projcet。定义它的build.gradle为java-gradle-plugin类型。

buildscript {
    repositories {
        jcenter()
        google()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.21"
    }
}

apply plugin: 'kotlin'
apply plugin: 'java-gradle-plugin'  //既不是lib也不是application,指定类型为gradle插件

repositories {
    jcenter()
    google()
}

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

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

gradlePlugin {
    plugins {
        version {
            id = 'com.hongyegroup.version'
            implementationClass = 'com.hongyegroup.version.DependencyVersionPlugin'
        }
    }
}
复制代码

入口文件:

class DependencyVersionPlugin : Plugin<Project> {
    override fun apply(project: Project) {
        //入口文件-空实现
    }
}
复制代码

定义版本的单例类:

object BuildConfig {
    const val compileSdkVersion = 29
    const val buildToolsVersion = "30.0.1"
    const val minSdkVersion = 21
    const val targetSdkVersion = 29
    const val versionCode = 100
    const val versionName = "1.0.0"
}
复制代码

使用的时候:可以很清楚的看到不同的依赖方式都已经注明。

android {
    compileSdkVersion BuildConfig.compileSdkVersion
    buildToolsVersion BuildConfig.buildToolsVersion
    defaultConfig {
        minSdkVersion versions.minSdk   //使用dependent.gradle的依赖无法跳转
        targetSdkVersion versions.targetSdk  //修改gradle文件中的值,需要build

        versionCode BuildConfig.versionCode   //使用version方式管理的依赖,可以跳转
        versionName BuildConfig.versionName   //修改其中的值,无需build

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles 'consumer-rules.pro'

        multiDexEnabled true
        vectorDrawables.useSupportLibrary = true
    }
}

复制代码

三. gradle配合BuildConfig管理正式环境和测试环境变量

相信很多同学都是这么管理正式环境与测试环境的吧。

public class Constants {

//    //测试环境
//    public static final String API_BASE_URL = "http://baidu-api-dev.guabean.com";
//    //IM测试环境
//    public static final int TIMSDK_APPID = 123456789;

    //正式环境
    public static final String API_BASE_URL = "http://api.baidu.com";
    //IM正式环境
    public static final int TIMSDK_APPID = 987654321;

    //推送的正式环境
    //推送的测试环境
    //Web的正式环境  等等
}
复制代码

一旦项目大了,需要配置的东西多了,那切换环境的时候岂不是要断手。其实我们可以在gradle中配置,配合BuildConfig的方式来配置正式与测试环境的变量。

config.gradle:

ext {

//    isLocalRelease = true     //本地打包环境  release设置true
      isLocalRelease = false     //本地打包环境 debug设置false


//    isReleaseUrl = true       //使用的服务器域名的环境, 正式环境设置true
    isReleaseUrl = false       //使用的服务器域名的环境,测试环境设置false (线上环境)


    // 测试环境的域名
    baseUrl_dev = 'http://baidu-api-dev.guabean.com'
    // 正式环境的域名
    baseUrl_relese = 'https://api.baidu.com'

    //极光测试环境key
    jpush_key_dev = '12345678'
    //极光正式环境key
    jpush_key_relese = '87654321'
   
    //Web地址等等
}
复制代码

使用:我们在底层库中,拿到它的全部值,根据是否是测试环境,来配置不同的值。 如cptServer的build.gradle:

apply from: "../lib_default_config.gradle"
apply plugin: 'dagger.hilt.android.plugin'

android {

    defaultConfig {
        //读取配置表的值
        boolean mIsReleaseUrl = rootProject.ext.isReleaseUrl
        //判断是正式环境还是测试环境
        if (mIsReleaseUrl) {
            String baseUrlRelese = rootProject.ext.baseUrl_relese
            buildConfigField 'String', 'Base_Url', "\"${baseUrlRelese}\""

        } else {
            String baseUrlDev = rootProject.ext.baseUrl_dev
            buildConfigField 'String', 'Base_Url', "\"${baseUrlDev}\""

        }

    }

}

dependencies {
    //底层
    api project(':cs_baselib')
}
复制代码

当我们使用的时候:就可以直接拿BuildConfig中的值

public class Constants {

    public static final String BASE_URL = BuildConfig.Base_Url;

    ...
}
复制代码

我们切换环境的时候,也只需要修改config.gradle的环境true和false就行了。这样就算再多的web和api key都可以很方便的管理。

四. gradle文件的继承与封装,完全的统一组件的依赖版本

组件化开发的过程中,各个组件的build.gradle依赖不同的库,导致各个版本不同,容易导致不兼容的问题。

如图,我们封装了gradle的内部实现,不同的级别模块依赖不同的gradle。

例如lib库依赖 lib_default_config.gradle。

子组件依赖模块 module_default_config.gradle。

运行模块如app或者独立子模块运行模块依赖 runing_default_config.gradle。

lib_base_config.gradle中定义了常规的gradle配置,和一些指定版本的配置。这个是用于其他的gradle继承的,一般不单独使用,代码如下:

apply plugin: 'dagger.hilt.android.plugin'

//基类的gradle配置
kapt {  //ARouter的编译配置
    arguments {
        arg("AROUTER_MODULE_NAME", project.getName())
    }
}

android {
    compileSdk versions.compileSdk

    defaultConfig {
        minSdk versions.minSdk
        targetSdk versions.targetSdk

        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles 'consumer-rules.pro'

        multiDexEnabled true
        vectorDrawables.useSupportLibrary = true

        javaCompileOptions {  //Hilt的编译配置
            annotationProcessorOptions {
                arguments += ["foo" : "bar"]
            }
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            multiDexKeepProguard file('multidex-config.pro')
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
        debug {
            multiDexKeepProguard file('multidex-config.pro')
        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        freeCompilerArgs = ['-Xjvm-default=enable']
        jvmTarget = JavaVersion.VERSION_1_8
        useIR = true
    }

    lintOptions {
        checkReleaseBuilds false
    }

    packagingOptions {
        resources {
            excludes += '/META-INF/{AL2.0,LGPL2.1}'
        }
    }

}

configurations.all {

    resolutionStrategy.force 'androidx.multidex:multidex:2.0.1'
    resolutionStrategy.force 'androidx.annotation:annotation:1.2.0'
    resolutionStrategy.force 'androidx.transition:transition:1.3.1'
    resolutionStrategy.force 'androidx.lifecycle:lifecycle-common:2.3.1'
    resolutionStrategy.force 'androidx.recyclerview:recyclerview:1.2.0'
}

dependencies {
    api fileTree(dir: 'libs', include: ['*.jar'])

    //每个模块都要实现的依赖
    //Test
    testImplementation deps.android.junit
    androidTestImplementation deps.android.test_junit
    androidTestImplementation deps.android.test_espresso
    //依赖注入
    implementation deps.support.hilt
    kapt deps.support.hilt_kapt

    //ARouter路由
    implementation (deps.support.arouter){
        exclude group: 'com.android.support'
        exclude group: 'androidx.appcompat'
        exclude group: 'com.google.android.material'
        exclude group: 'androidx.activity'
    }
    //ARouter的注解处理器
    kapt deps.support.arouter_kapt

}
复制代码

lib_default_config.gradle的配置,用于Lib库的使用

//底层依赖库的gradle配置,可以依赖这个配置 再配置别的依赖
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'

apply from: rootProject.file('lib_base_config.gradle')  //重复的配置统一由基类提供
复制代码

使用:比如我引用一个lib_popup库,它的build.gradle:

apply from: "../lib_default_config.gradle"

dependencies {
     //继承了之前的dependencies,再定义一些我需要的依赖库
    implementation deps.android.appcompat
    api deps.support.easy_adapter
}
复制代码

module_default_config.gradle的配置,用于子组件的使用

//默认的模块初始化gradle配置,可以依赖这个配置 再配置别的依赖
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'

apply from: rootProject.file('lib_base_config.gradle')  //重复的配置统一由基类提供

android {
    buildFeatures {
        dataBinding = true
        viewBinding = true
    }
}

dependencies {

    implementation project(':cs_cptServices')   //Module模块默认添加Service模块的
}
复制代码

如cpt_newsfeed,朋友圈组件的build.gradle

apply from: "../module_default_config.gradle"

dependencies {
    //九宫格控件
    implementation project(':cs_ninegrid')
}
复制代码

runing_default_config.gradle的配置用于子组件独立运行模块或者app模块。

//运行模块初始化gradle配置,可以依赖这个配置 再配置别的依赖
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'dagger.hilt.android.plugin'

//运行模块可以添加路由
apply plugin: 'com.alibaba.arouter'

apply from: rootProject.file('lib_base_config.gradle')  //重复的配置统一由基类提供


android {
    defaultConfig {
        versionCode 100
        versionName "1.0.0"
        applicationId "com.hongyegroup.running"
    }

    buildFeatures {
        dataBinding = true
        viewBinding = true
    }
}

dependencies {

    //依赖注入
    implementation deps.support.hilt
    kapt deps.support.hilt_kapt

    implementation project(':cs_cptServices')  //运行模块默认添加Service模块的
}
复制代码

使用的时候,如app模块,程序的入口,它的build.gradle如下:

apply from: "../runing_default_config.gradle"

android {
    defaultConfig {
        versionCode 100
        versionName "1.0.0"
        applicationId "com.xxgroup.xxapp"
    }
}

dependencies {
    //依赖模块
    implementation project(':cs_cptServices')
    implementation project(':cpt_auth')
    implementation project(':cpt_main')
    implementation project(':cpt_parttime')
    implementation project(':cpt_newsfeed')
    implementation project(':cpt_ewallet')
    implementation project(':cpt_im')
    implementation project(':cpt_profile')
}
复制代码


这样就很方便的管理Gradle版本,配置等信息,一旦有修改也不至于全部的模块的gradle文件都要改。

我们再基类的gradle配置中指定了版本,那么全部的模块都是使用统一的版本,再配合引入库的时候exclude的操作,完全不用担心引入多个版本导致兼容性的问题。

版本管理源码在此,最后感谢完结了。

作者:newki
链接:https://juejin.cn/post/7098878694449479688
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值