依赖-管理依赖的版本(传递(transitive)\排除(exclude)\强制(force)\动态版本(+))

本文转载自原文链接

我主要使用了exclude,使用exculde去除重复的依赖,比如 引入的多个第三方包都包含 okhttp  就可以使用该方法去除:

  A: compile ‘com.test.aaa’

  B :  compile     'com.test.bbb'

  C:   compile     'com.test.ccc'

  D:   compile    'com.squarequ.okhttp3'

  例如 自己的项目中依赖了 okhttp 还依赖了A B C 三个第三方包,A B C  中都依赖了 okhttp ,直接编译 不能通过 报错

Error:Error converting bytecode to dex:

Cause: com.android.dex.DexException: Multiple dex files define Lokhttp3/Address;

这样 就要去除 A B C 中的okhttp ,使用方法

  compile ('com.test.aaa'){

        exclude group'com.squarequ.okhttp3'

}

这样就去掉了A 依赖中的okhttp . B  C 同理。


什么是传递依赖

  在Maven仓库中,构件通过POM(一种XML文件)来描述相关信息以及传递性依赖。Gradle 可以通过分析该文件获取获取所以依赖以及依赖的依赖和依赖的依赖的依赖,为了更加直观的表述,可以通过下面的输出结果了解。

+--- org.springframework:spring-web:4.3.4.RELEASE
|    |    +--- org.springframework:spring-aop:4.3.4.RELEASE
|    |    +--- org.springframework:spring-beans:4.3.4.RELEASE
|    |    +--- org.springframework:spring-context:4.3.4.RELEASE
|    |    \--- org.springframework:spring-core:4.3.4.RELEASE
  • 1
  • 2
  • 3
  • 4
  • 5

  可以看到,我们的项目依赖了spring-web,然而spirng-web却依赖了一众spring的全家桶,借助Gradle的传递性依赖特性,你无需再你的脚本中把这些依赖都声明一遍,你只需要简单的一行,Gradle便会帮你将传递性依赖一起下载下来。

compile `org.springframework:spring-web:4.3.4.RELEASE`
  • 1

 传递依赖特性可以轻松地通过transitive参数进行开启或关闭,上面的示例中如果要忽略spring-web的传递性依赖可以采用指定 transitive = false 的方式来关闭依赖传递特性,也可以采用添加@jar的方式忽略该依赖的所有传递性依赖。

compile("org.springframework:spring-web:4.3.4.RELEASE") {
    transitive = false
}
  • 1
  • 2
  • 3
compile `org.springframework:spring-web:4.3.4.RELEASE@jar`
  • 1

下面的语句,可以全局性的关闭依赖传递特性。

configurations.all {
   transitive = false
}
  • 1
  • 2
  • 3

排除依赖

   有些时候你可能需要排除一些传递性依赖中的某个模块,此时便不能靠单纯的关闭依赖传递特性来解决了。这时exclude就该登场了,如果说@jar彻底的解决了传递问题,那么exclude则是部分解决了传递问题。然而实际上exclude肯能还会用的频率更更频繁一些,比如下面几种情况。

  • 依赖冲突时,如果有两个依赖引用了相同jar包的不同版本时,默认情况下gradle会采用最新版本的jar包,此时可以通过排除选项来排除。
  • 运行期无需此模块的。
  • 无法正常获取到此传递依赖,远程仓库都不存在的。
  • 版权原因需要排除的。
  • 其他原因。

可以通过configuration配置或者在依赖声明时添加exclude的方式来排除指定的引用。

  exclude可以接收group和module两个参数,这两个参数可以单独使用也可以搭配使用,其中module可以理解为对应GAV中的artifactId,也就是compile group: 'org.gradle.test.classifiers', name: 'service', version: '1.0'中的中间name部分。

configurations {
    //编译期排除commons模块
    compile.exclude module: 'commons'
    //在整个构建过程中排除pkaq.tiger:share
    all*.exclude group: 'pkaq.tiger', module: 'share'
}

dependencies {
    compile("pkaq.tiger:web:1.0") {
        exclude module: 'share'
    }       
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

使用强制版本

  当然,有时候你可能仅仅是需要强制使用某个统一的依赖版本,而不是排除他们,那么此时force就该登场了。指定force = true属性可以冲突时优先使用该版本进行解决。

compile('org.hibernate:hibernate:3.1') {
    force = true
}
  • 1
  • 2
  • 3

全局配置强制使用某个版本的依赖来解决依赖冲突中出现的依赖

configurations.all {
   resolutionStrategy {
       force 'org.hamcrest:hamcrest-core:1.3'
   }
}
  • 1
  • 2
  • 3
  • 4
  • 5

使用动态版本

  如果你想让你的工程始终采用最新依赖,那么Gradle提供了一种方式可以始终保证采用依赖的最新版本而无需每次手工检查修改版本。 
  使用加号+,可以让Gradle在每次执行构建时检查远程仓库是否存在该依赖的新版本,如果存在新版本则下载选用最新版本。当然也可以指定依赖某个大版本下的最新子版本,1.+表示始终采用该依赖最新的1.x版本的最新依赖。

compile 'org.springframework:spring-web:+'
  • 1

虽然这是看上去十分风骚的一种用法,但这无疑会降低你系统构建的速度同时提高构建失败的风险。因为Gradle不得不每次检查远程仓库是否存在最新版本,同时新版本也可能带来无法预知的兼容性问题,比如quartz2.x较之于quartz1.x,common-lang3较之于common-lang等。

一个综合示例

compile('org.hibernate:hibernate:3.1') {
 // 冲突时优先使用该版本
 force = true

 // 依据构建名称排除
 exclude module: 'cglib' 
 // 依据组织名称排除
 exclude group: 'org.jmock' 
 // 依据组织名称+构件名称排除
 exclude group: 'org.unwanted', module: 'iAmBuggy' 

 // 为本依赖关闭依赖传递特性
 transitive = false
}
<think>好的,我现在需要解决用户的问题:在清理Gradle缓存后,仍然生成了特定预览版的aar文件(15.0.35.26-preview版本),如何避免这种情况。让我先理清楚问题的背景和可能的解决方案。 首先,用户提到了之前处理过类似的问题,比如通过手动下载依赖文件并放入指定路径,或者调整依赖版本号。现在的问题是在清理缓存后,Gradle依然生成了不需要的预览版aar文件。这可能涉及到Gradle依赖解析机制或项目配置的问题。 我需要考虑几个方面: 1. **依赖锁定**Gradle有时候可能会动态获取依赖,尤其是当版本号被指定为动态或范围时,导致每次构建时拉取最新版本。用户可能没有固定版本号,导致Gradle下载了最新的预览版。 2. **缓存机制**:即使清理了本地缓存,Gradle可能仍然从远程仓库重新下载相同的版本,如果项目配置中仍然要求该版本的话。 3. **项目配置检查**:需要检查项目中的build.gradle文件,查看是否有地方指定了动态版本,比如使用`+`或`latest.release`等,或者是否有依赖传递引入了该预览版。 4. **依赖树分析**:通过Gradle依赖树分析工具,找出是哪个模块引入了这个预览版的aar,然后排除或覆盖它。 5. **强制版本**:在构建脚本中强制指定所需的版本,覆盖传递依赖带来的版本。 接下来,我需要参考用户提供的引用资料。例如,引用[3]中提到,某个依赖版本引用了不存在的文件,解决方法是降低版本。类似地,用户可能需要固定相关依赖版本,避免Gradle拉取预览版。 可能的解决步骤: 1. **检查依赖版本**:在项目的build.gradle文件中,检查所有依赖项是否有使用动态版本,例如`15.0.+`或`15.0.35.26-preview`这样的写法。确保所有依赖都指定了具体的稳定版本号。 2. **使用依赖约束**:在Gradle中可以通过约束来强制模块使用特定版本,例如: ```groovy dependencies { implementation('com.example:library') { version { strictly '15.0.35' } } } ``` 3. **排除传递依赖**:如果预览版是通过其他依赖传递引入的,可以在依赖声明中排除该模块: ```groovy implementation('com.example:some-dependency') { exclude group: 'com.preview.group', module: 'preview-module' } ``` 4. **分析依赖**:运行`./gradlew :app:dependencies`(假设模块名为app)查看依赖树,找到引入预览版aar的路径,然后根据路径进行排除版本覆盖。 5. **使用resolutionStrategy**:在build.gradle中配置强制使用特定版本: ```groovy configurations.all { resolutionStrategy { force 'com.preview.group:preview-module:15.0.35' } } ``` 6. **检查仓库设置**:确保项目的仓库配置中没有包含会提供预览版的仓库,或者调整仓库顺序,优先使用稳定版仓库。 可能的错误点在于用户可能没有正确锁定依赖版本,或者某个传递依赖引入了预览版。例如,如果某个库的依赖声明为`com.example:lib:15.+`,那么Gradle可能会解析到最新的15.x.x版本,包括预览版。因此,需要明确指定版本号,避免动态版本。 另外,用户可能在清理缓存后,Gradle重新解析依赖时,由于配置未改,再次下载了相同的预览版。因此,修改项目配置是关键。 总结可能的解决方案步骤: 1. 确定具体是哪个依赖引入了预览版aar。 2. 在build.gradle中固定该依赖版本为稳定版。 3. 使用排除强制版本来避免预览版被引入。 4. 验证依赖树是否不再包含该预览版。</think>要避免清理Gradle缓存后仍生成特定预览版(如15.0.35.26-preview)的aar文件,可通过以下步骤解决: ### 一、定位依赖来源 1. **分析依赖** 执行以下命令查看完整的依赖关系链: ```bash ./gradlew :app:dependencies --configuration releaseRuntimeClasspath ``` 在输出中搜索`15.0.35.26-preview`,确定是**直接依赖还是传递依赖**引入的预览版[^2]。 --- ### 二、固定依赖版本 2. **修改build.gradle** - 如果预览版是**直接依赖**,将其版本号改为稳定版: ```groovy implementation 'com.example:library:15.0.35' // 替换为稳定版本 ``` - 如果是**传递依赖**,通过`resolutionStrategy`强制覆盖版本: ```groovy configurations.all { resolutionStrategy { force 'com.example:transitive-lib:15.0.35' // 强制使用稳定版 } } ``` --- ### 三、排除动态版本声明 3. **检查动态版本符号** 避免使用`+`、`latest.release`等动态版本标识符: ```groovy // 错误示例(可能拉取预览版) implementation 'com.example:lib:15.+' // 正确示例(固定版本) implementation 'com.example:lib:15.0.35' ``` --- ### 四、清理并重建项目 4. **彻底清理缓存** 执行以下命令清除Gradle缓存: ```bash ./gradlew cleanBuildCache rm -rf ~/.gradle/caches/ ``` 重新构建项目验证是否生效。 --- ### 五、配置仓库优先级 5. **调整仓库顺序** 在`build.gradle`中将**稳定版仓库**(如Maven Central)放在预览仓库之前: ```groovy repositories { mavenCentral() // 将包含预览版的仓库放在下方 maven { url 'https://preview.repo.example.com' } } ``` --- ### 六、验证结果 6. **检查生成的依赖** 构建后再次运行依赖树分析命令,确认预览版已替换为稳定版。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值