Gradle依赖那些事

先安利一个查询项目依赖的命令:./gradlew 模块名:dependencies

一、exclude

用法:exclude group:' ', module: ' ' 【 group和module两个参数可分别单独使用 】
说明:排除某个依赖,可解决部分传递依赖。

使用场景:

  • 解决依赖冲突。若两个模块使用相同 jar 包的不同版本,gradle 默认会使用最新版本的 jar 包,此时可以通过 exclude 排除冲突。(版本冲突带来的问题最主要是API类或方法移除。)
  • 运行期无需此模块。
  • 传递依赖无法找到时,可通过 exclude 排除。
  • 版权原因需排除。
compile 'com.android.support:support-v4:26.1.0'
    
    // 单独排除某个模块中的依赖  
    compile('com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.11.0@aar') {
        exclude group: 'com.android.support'
    }

    // 排除所有子依赖中的support依赖,统一使用主项目中的版本
    configurations {
       all*.exclude group: 'com.android.support'
    }

用法:主工程使用的 support 包版本为 26.1.0,使用 exclude group: 'com.android.support' 可以将 advrecyclerview 模块中的 support 排除掉,统一使用主工程的 v26.1.0 版本。不管advrecyclerview依赖的该support包版本时高于还是低于主工程版本。

假设 advrecyclerview 中依赖的 support相关版本为 27.0.0,排除依赖前,项目依赖关系为:

project :shop
| + - com.android.support:appcompat-v7:26.1.0 ()
| + - com.android.support:support-v4:26.1.0 (
)
| + - com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.11.0
| | + - - - com.android.support:appcompat-v7:27.0.0 -> 26.1.0 ()
| | \ - - - com.android.support:recyclerview-v7:27.0.0 -> 26.1.0
| | + - - - - - com.android.support:support-annotations:26.1.0
| | + - - - - - com.android.support:support-compat:26.1.0 (
)
| | \ - - - - - com.android.support:support-core-ui:26.1.0 (*)

对应的在build后,External Libraries 中会同时存在 support v27.0.0 和 v26.1.0 两种版本的aar依赖。

排除 support 依赖后,External Libraries 就只会存在 v26.1.0 版本的aar。对应的依赖关系如下:

project :shop
| + - com.android.support:appcompat-v7:26.1.0 ()
| + - com.android.support:support-v4:26.1.0 (
)
| + - com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.11.0

二、transitive

用法:transitive = true | false

说明:是否传递本身的依赖给宿主程序(使用传递依赖时,Gradle 会将传递依赖一起下载下来。compile 默认是开启传递依赖)

// 统一指定 transitive
configurations.all {
       transitive = false
}

// 单独指定依赖项的 transitive 
compile('com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.11.0@aar') {
    transitive = false
}

transitive = true,依赖同于没有使用 exclude 排除依赖 ,每个包的依赖项都会被递归分析并添加进来。
transitive = false,则依赖关系同于用 exclude 排除依赖。

Tips: exclude 和 transitive 可以同时使用,exclude会排除 transitive=true时的一些传递依赖。

三、force

用法:force = true
作用:强制使用某个版本。出现冲突时,优先使用该版本解决。

// 强制使用 support-v4 26.1.0版本
compile('com.android.support:support-v4:26.1.0') {
   force = true
}
四、动态版本(不建议使用)

使用场景:保持工程依赖都是最新版本。
使用方式:+,可以让gradle每次构建时检查远程仓库是否存在最新版本,若存在则下载。也可指定某个大版本下的最新子版本,1.+,表示始终依赖最新的 1.x 版本。

compile 'com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.+'

缺点:

  • 减低构建速度并且会提高构建失败风险;
  • 新版本可能带来兼容性问题。
五、综合实例
compile('org.hibernate:hibernate:3.1') {
     // 冲突时优先使用该版本
     force = true

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

     // 为本依赖关闭依赖传递特性
     transitive = false
}
六、问题

1.项目中多个模块依赖同一个依赖 D 的不同版本,如何保持每个模块直接使用自己本身 compile 的依赖版本呢?
A:如果是直接 compile 包含不同版本的依赖,会造成依赖冲突。有一种方式可以直接将模块打包成本地 jar 。打包成本地 aar 文件,也是不行,因为本地 aar 依赖,需要外部也 compile aar 中依赖的一些架包,否则会找不到。

另一种方式就很有效保证 各个模块保持自己依赖的版本,而不用在意其他版本并且担心产生冲突。具体如下:

configurations.all {
// 遍历所有的依赖,根据 moduleName 使用对应的版本。确实可行
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
    def requested = details.requested
    if (requested.group == 'com.android.support') {
        if (requested.name.startsWith("multidex")) {
            details.useVersion '26.1.0'
        } else if (requested.name.startsWith("advrecyclerview")) {
            details.useVersion '27.0.0'
        } else {
            details.useVersion '25.3.0'
        }
    }
  }
}
七、本地aar依赖问题

场景:主工程app -> shop模块 -> 依赖本地aar

问题:在主工程依赖 shop 模块的远程依赖时,无法找到依赖的本地 aar 相关。
解决:将 本地 aar 放到远端,也是用远程依赖。
原因:主要在于Android 3.0 后本地 aar 依赖无法越级传递依赖。可以看远端 shop模块 maven打包时生成的 .pom 文件,查看具体依赖,发现gradle 会把本地 aar 依赖也当做一份远端依赖进行配置,但是没有group等信息,如此在主工程中依赖 shop 模块是,直接编译不通过,因为会视为远端仓库的依赖,但实际并不存在。(根本原因未知)

问题:本地 jar 依赖和 本地 aar 依赖区别。

  • jar 文件只包含编译好的 .class 文件和清单文件,不包含资源文件。所以如果没有 res 资源文件,可以在打包时,将 packaging 配置为 jar 格式;
  • aar 文件包含 class 以及 /res 目录下的所有资源文件。
    -查看 gradle 下载的远程依赖区别就很明显:
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342