zoukankan      html  css  js  c++  java
  • 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 下载的远程依赖区别就很明显:
      image

    本文转自:https://www.jianshu.com/p/a38904a10988

  • 相关阅读:
    3170: [Tjoi 2013]松鼠聚会
    1577: [Usaco2009 Feb]庙会捷运Fair Shuttle
    时间管理小强升级记
    Lifray Portlet
    反面模式
    LiferayFAQ(持续更新)
    【转载】JRockit检测Tomcat内存溢出JAVA内存泄漏问题
    Liferay环境搭建
    QQ登陆篇
    设计模式MM版
  • 原文地址:https://www.cnblogs.com/sishuiliuyun/p/15424764.html
Copyright © 2011-2022 走看看