一文彻底搞清 Gradle 依赖【转】

来源:曾是放牛娃

www.jianshu.com/p/59fd653a54d2

转自:https://mp.weixin.qq.com/s?__biz=MzA3MDMyMjkzNg==&mid=2652262838&idx=1&sn=e160fb15de0518fd207fedf5835b3814&chksm=84dc6e21b3abe73735a917ee8c79b3b422f460bb198c3dbc23e0ab776c846ca4fdc22a94e57d&mpshare=1&scene=24&srcid=1221sg5Pt9j9t1TKKqVZgbDz#rd

之前对Android Gradle构建的依赖一直傻傻分不清,这段时间正好接入集团的一个二方库,踩了很多坑,也顺带把Gradle依赖这块搞清楚了,主要整理了下Gradle依赖的类型、依赖配置、如何查看依赖、依赖冲突如何解决。

 

依赖类型

dependencies DSL标签是标准Gradle API中的一部分,而不是Android Gradle插件的特性,所以它不属于android标签。

依赖有三种方式,如下面的例子:

apply plugin: ‘com.android.application‘

android { ... }

dependencies {    // Dependency on a local library module    implementation project(":mylibrary")

    // Dependency on local binaries    implementation fileTree(dir: ‘libs‘, include: [‘*.jar‘])

    // Dependency on a remote binary    implementation ‘com.example.android:app-magic:12.3‘}

本地library模块依赖

implementation project(":mylibrary")

这种依赖方式是直接依赖本地库工程代码的(需要注意的是,mylibrary的名字必须匹配在settings.gradle中include标签下定义的模块名字)。

 

本地二进制依赖

implementation fileTree(dir: ‘libs‘, include: [‘*.jar‘])

这种依赖方式是依赖工程中的 module_name/libs/目录下的Jar文件(注意Gradle的路径是相对于build.gradle文件来读取的,所以上面是这样的相对路径)。

如果只想依赖单个特定本地二进制库,可以如下配置:

implementation files(‘libs/foo.jar‘, ‘libs/bar.jar‘)

远程二进制依赖

implementation ‘com.example.android:app-magic:12.3‘

上面是简写的方式,这种依赖完整的写法如下:

implementation group: ‘com.example.android‘, name: ‘app-magic‘, version: ‘12.3‘

group、name、version共同定位一个远程依赖库。需要注意的点是,version最好不要写成"12.3+"这种方式,除非有明确的预期,因为非预期的版本更新会带来构建问题。远程依赖需要在repositories标签下声明远程仓库,例如jcenter()、google()、maven仓库等。

依赖配置

目前Gradle版本支持的依赖配置有:implementation、api、compileOnly、runtimeOnly和annotationProcessor,已经废弃的配置有:compile、provided、apk、providedCompile。此外依赖配置还可以加一些配置项,例如AndroidTestImplementation、debugApi等等。

常用的是implementation、api、compileOnly三个依赖配置,含义如下:

  • implementation
    与compile对应,会添加依赖到编译路径,并且会将依赖打包到输出(aar或apk),但是在编译时不会将依赖的实现暴露给其他module,也就是只有在运行时其他module才能访问这个依赖中的实现。使用这个配置,可以显著提升构建时间,因为它可以减少重新编译的module的数量。建议,尽量使用这个依赖配置。
  • api
    与compile对应,功能完全一样,会添加依赖到编译路径,并且会将依赖打包到输出(aar或apk),与implementation不同,这个依赖可以传递,其他module无论在编译时和运行时都可以访问这个依赖的实现,也就是会泄漏一些不应该不使用的实现。举个例子,A依赖B,B依赖C,如果都是使用api配置的话,A可以直接使用C中的类(编译时和运行时),而如果是使用implementation配置的话,在编译时,A是无法访问C中的类的。
  • compileOnly
    与provided对应,Gradle把依赖加到编译路径,编译时使用,不会打包到输出(aar或apk)。这可以减少输出的体积,在只在编译时需要,在运行时可选的情况,很有用。
  • runtimeOnly
    与apk对应,gradle添加依赖只打包到APK,运行时使用,但不会添加到编译路径。这个没有使用过。
  • annotationProcessor
    与compile对应,用于注解处理器的依赖配置,这个没用过。

查看依赖树

可以查看单个module或者这个project的依赖,通过运行依赖的Gradle任务,如下:

1、View -> Tools Windows -> Gradle(或者点击右侧的Gradle栏);

2、展开 AppName -> Tasks -> android,然后双击运行AndroidDependencies。运行完,就会在Run窗口打出依赖树了。

 

依赖冲突解决

随着很多依赖加入到项目中,难免会出现依赖冲突,出现依赖冲突如何解决?

定位冲突

依赖冲突可能会报类似下面的错误:

Program type already present com.example.MyClass

通过查找类的方式(command + O)定位到冲突的依赖,进行排除。

如何排除依赖

1、dependencies中排除(细粒度)

compile(‘com.taobao.android:accs-huawei:[email protected]‘) {        transitive = true        exclude group: ‘com.taobao.android‘, module: ‘accs_sdk_taobao‘}

2、全局配置排除

configurations {    compile.exclude module: ‘cglib‘    //全局排除原有的tnet jar包与so包分离的配置,统一使用aar包中的内容    all*.exclude group: ‘com.taobao.android‘, module: ‘tnet-jni‘    all*.exclude group: ‘com.taobao.android‘, module: ‘tnet-so‘}

3、禁用依赖传递

compile(‘com.zhyea:ar4j:1.0‘) {    transitive = false}

configurations.all {    transitive = false}

还可以在单个依赖项中使用@jar标识符忽略传递依赖:

compile ‘com.zhyea:ar4j:1.0@jar‘

4、强制使用某个版本

如果某个依赖项是必需的,而又存在依赖冲突时,此时没必要逐个进行排除,可以使用force属性标识需要进行依赖统一。当然这也是可以全局配置的:

compile(‘com.zhyea:ar4j:1.0‘) {    force = true}

configurations.all {    resolutionStrategy {        force ‘org.hamcrest:hamcrest-core:1.3‘    }}

5、在打包时排除依赖

先看一个示例:

task zip(type: Zip) {    into(‘lib‘) {        from(configurations.runtime) {            exclude ‘*unwanted*‘, ‘*log*‘        }    }    into(‘‘) {        from jar        from ‘doc‘    }}

代码表示在打zip包的时候会过滤掉名称中包含“unwanted”和“log”的jar包。这里调用的exclude方法的参数和前面的例子不太一样,前面的参数多是map结构,这里则是一个正则表达式字符串。

也可以使用在打包时调用include方法选择只打包某些需要的依赖项:

task zip(type: Zip) {    into(‘lib‘) {        from(configurations.runtime) {            include ‘*ar4j*‘, ‘*spring*‘        }    }    into(‘‘) {        from jar        from ‘doc‘    }}

主要是使用dependencies中排除和全局配置排除。

原文地址:https://www.cnblogs.com/longjunhao/p/10160831.html

时间: 2024-10-08 21:39:51

一文彻底搞清 Gradle 依赖【转】的相关文章

Android Gradle 依赖配置:implementation & api

背景: Android Gradle plugin 3.0开始(对应Gradle版本 4.1及以上),原有的依赖配置类型compile已经被废弃,开始使用implementation.api和annotationProcessor类型分别替代.对应的,这三种替代配置类型针对具体的使用场景,具有不同的依赖行为.其中,implementation和api依赖又相对最为常用,对其具体含义也需要理解清,在实际项目中选择依赖配置时,也才能游刃有余. 首先看一下Android官方文档中关于依赖配置的详细介绍

android studio的 gradle 依赖同步错误解决方法

android studio 和eclipse都比较臃肿,bug一堆,个人都不喜欢用.但谷歌官方指定as(android studio)我也就开始了as上的开发.我一直被依赖问题整的si去活来,今天在编译 https://github.com/4455jkjh/Apktool-android,一个安卓上的比较强大的反bian译软件,我的as是最新版,变易又遇见了在这个问题,在此记录一下排错技巧.本人不是专业安卓程序员,难免描述出错,不对或不妥的地方请大佬在评论区批评指正. 要想理解该文就要简单说

强制清除 gradle 依赖缓存

今天同事误上传一个库,然后又删除了... 我刚好把他上传的库给down下来了...然后项目一直报错,clean...重新编译...删build文件....全都不管用===== 好几个人研究了好久,只能猜测是缓存问题...把项目的缓存全删了没用....那应该是gradle缓存的问题... 可以我电脑上的gradle版本着实不少,路径很难找...真是难办.... 最后下班,同事全跑了....只能自己继续找!!! 回头一想,gradle缓存问题挺常见的,同行们应该有相应的博客...赶紧百度一下...

android gradle 依赖项配置变更

在gradle-4.0之前的版本,引入依赖包时,都是按下面的做法 compile 'com.facebook.fresco:animated-gif:0.13.0' 但Android Studio 版本更新至3.0 的gradle-4.0版本中,包依赖配置语句做了修改,变成以下用法: implementation 'com.facebook.fresco:animated-gif:0.13.0' 或者 api 'com.facebook.fresco:animated-gif:0.13.0' 以

【10分钟学Spring】:(二)一文搞懂spring依赖注入(DI)

Spring最基础的特性就是创建bean.管理bean之间的依赖关系.下面通过具体实例演示该如何装配我们应用中的bean. Spring提供了三种主要的装配机制 在xml中进行显示的配置 在Java中进行显示的配置 隐式的bean发现机制和自动装配 三种装配方式可依据个人喜好选择使用,无限制.不过应尽可能地使用自动转配机制,因为可以少一大推的配置.在你必须要使用显示配置时,比如要装配一些第三方的bean对象是,可以使用显示的配置.推荐使用类型安全且比xml更加强大的JavaConfig. 自动装

Dubbo教程文档--Dubbo服务依赖检查

Dubbo官方文档: 用户指南 >> 示例 >> 启动时检查

Gradle用户指南(章8:依赖关系管理基础)

章8:依赖关系管理基础 本章将介绍一些gradle依赖关系管理的基础 什么是依赖关系管理? 简略的说,依赖管理是由两部分组成的.首先,gradle需要知道你要构建或者运行的项目,以便找到它们.我们将这些导入的文件视为项目的依赖.第二,gradle需要构建或者打包你的项目产品.我们将这些导出的文件视为项目的发布.下面,让我们在细节上更多的了解这两个方面. 大部分项目都不是完全彻底的独立的.它们需要其他项目的构建文件,以便编译.测试等等.例如,为了在我的项目中使用Hibernate,当编译我的源文件

Android使用Gradle统一配置依赖版本

前言 目前的Android开发为了减少编译时间,开发效率,大多都采用模块化,组件化的开发方式. 采用这种方式不可避免的将会用到多个Library. 那么当我们协同开发时,如何处理每个人的版本统一呢? 我想大部分人应该都在使用Gradle来依赖管理,还没有使用的去面壁思过,Gradle使用起来简直太好用了,举个例子,我们想依赖个support-v4包,直接一句话: compile 'com.android.support:support-v4:25.1.0' 但是不知道你们发现一些问题没有?比如以

gradle学习之旅(九) 依赖配置

包括本节的接下来三节中分别学习gradle依赖管理中是三个重要感念:依赖配置.依赖声明.仓库配置和使用 什么是配置 配置就是依赖的配置 插件可以引入配置来定义依赖的作用域(第四节的java插件),比如java插件通过compile配置添加编译产品源代码所需的依赖. 配置的API表示 配置可以直接在项目的根级别添加和访问,可以直接使用插件提供的配置,也可以声明自己的配置. 类似于taskContainer,每个项目也有一个ConfigurationContainer类的容器来管理相应的配置 配置在