Android Gradle 的 dependency

Android 默认使用 Gradle 来编译 Project,并且开发了一套支持 Android 编译的 Gradle 插件,Android Plugin for Gradle,使用 Android Studio 新建的默认工程的 build.gradle 文件中就能够看到当前使用的插件版本

dependencies {
    classpath 'com.android.tools.build:gradle:3.1.2'
}

尽管利用 Gradle 来编译,但 Android 做了特殊化处理,并非所有的 Gradle 支持的依赖配置都能应用到 Android Gradle 编译中,因此必须使用 Android 官方定义的依赖

有哪些依赖的方式

  • 本地 bin 方式
  • 远程 bin 方式
  • 本地 module 方式

注意,这些依赖项属于某个 Module 下的 build.gradle

本地 bin 方式,例如本地的 jar 文件

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

这种写法,是指定 Module-name/libs 中所有 jar,当然也可以改为指定具体的 jar

implementation files('libs/xxx.jar', 'libs/yyy.jar')

远程 bin 方式,自动从远程服务器下载依赖,方便多人协作的项目

implementation 'com.android.support.constraint:constraint-layout:1.1.2'

这种写法,其实是如下写法的简写

implementation group: 'com.android.support.constraint', name:'constraint-layout', version:'1.1.2'

需要注意,如果使用的远程 bin 依赖是公司内部私服的话,还需要指定私服的 url,否则 Gradle 构建无法找到该依赖(下文提到如何添加仓库)

本地 module 方式,是依赖同一个 Project 下的其他 Module

implementation project(':mylib')

这里的 mylib 必须是 Project 下 settings.gradel 中 include 定义的某一个名字

有哪些常用的依赖配置

有的时候,我们希望依赖打包到 apk 中,有的时候,只在编译时使用,该如何指定?

  • implementation(老版本:compile)
  • compileOnly(老版本:provided)
  • runtimeOnly(老版本:apk)

implementation 会将依赖添加到编译的 classpath 中,在 module-name/build/intermediates/classes 中可以看到 class 文件,同时会打包到 apk 中供运行时使用

当我们要用到一个 Android 系统环境中不具备的第三方库时,就可以采用这种方式

compileOnly 会将依赖添加到编译的 classpath 中,但不打包到 apk,所以运行时无法使用

当我们要用到 framework 层的接口,就可以采用这种方式

runtimeOnly 不会将依赖添加到编译的 classpath ,但会打包到 apk

其他的配置项还包括 api,annotationProcessor,lintChecks,lintPublish

这里 api 方式要提一下,它类似于 implementation,区别是 implementation 编译选项项在编译期时其他的 Module 不能使用,只在运行时可以,api 则可以在编译期供其他 Module 使用。比如某个 Project 中的 moduleA 依赖了某个作为库的 moduleB,并且 moduleA 要使用 moduleB 的第三方依赖包,则 moduleB 的这个依赖包设置为 api 编译选项,才能让 moduleA 正常编译

排除冲突

有时会遇到,Module 中使用的 dependecy A 和 dependency B 都存在某个相同的库,这在编译时会发生冲突导致编译失败,报出以下错误

Program type already present com.abc.edc.MyClass

排除某个 dependency 中的重复项,使用 exclude 关键字

dependencies {
    implementation('com.a.b:cc-dd:1.0.0') {
        exclude group: 'com.abc.def', module: 'yyy'
    }
}

也可以把花括号放到小括号里面

dependencies {
    implementation('com.a.b:cc-dd:1.0.0', {
        exclude group: 'com.abc.def', module: 'yyy'
    })
}

特别注意,上述写法对 androidTestImplementation 编译选项无效,因为该编译选项强制按 implementation 方式依赖项目,要排除某个库需要单独这样指定

android.testVariants.all { variant ->
    variant.getCompileConfiguration().exclude group: 'com.android.support', module: 'support-annotations'
}

写法和 dependencies 处于同一级

指定远程仓库

在 Project 下的 build.gradle 中,新建项目时默认指定了 Google 的 Maven 仓库和 JCenter 仓库

allprojects {
    repositories {
        google()
        jcenter()
    }
}

要添加公司私服仓库,按这种方式填写

allprojects {
    repositories {
        google()
        jcenter()
        myCompany {
            url "https://repo.my.com/mycompany"
        }
        my {
            url 'https://maven.myCompany.com/'
            name 'myCompany'
        }
    }
}

Maven 的中央仓库和本地仓库命名为:mavenCentral(),mavenLocal()

注意,顺序越靠上的仓库,Gradle 则优先获取该仓库下的依赖

另外,如果要使用一些旧版本的库,并且在 Google Maven 代码库中已经找不到了,则使用 SDK Manager 下载离线 Google 代码库软件包,之后就可以添加依赖了(离线包一般存放在 ANDROID_HOME/extras)

依赖项的优先级

按照从上往下的顺序,优先级依次递减,例如

dependencies{
    LIB_A
    LIB_D
    LIB_B
    LIB_C
}

则优先级顺序为 A,D,B,C。这在合并资源或将清单元素从库中合并到应用中时很重要

发布了27 篇原创文章 · 获赞 3 · 访问量 5653

猜你喜欢

转载自blog.csdn.net/candyngwh/article/details/105356469