3 依赖关系,Android库及多项目设置(Dependencies, Android Libraries and Multi-project setup)

Gradle项目可以依赖于其他组件,这些组件可以是扩展的二进制包或其他Gradle项目。

3.1 依赖于二进制包(Dependencies on binary packages)

3.1.1 本地包(Local packages)

配置一个扩展jar包的依赖,你需要在compile配置添加一个依赖关系。以下代码片段添加了libs目录下所有jar包的依赖:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

android {
    ...
}

注意:**这个dependencies DSL元素是标准的Gradle API的一部分,所以不需要放置在android**元素中。

compile配置用于编译主应用,配置的所有东西都被添加到编译类路径(classpath)并且打包到最终的APK中。以下是添加依赖的其他可用配置:

  • compile:主应用
  • androidTestCompile:测试应用
  • debugCompile:debug构建类型(Build Type)
  • releaseCompile:release构建类型(Build Type)

因为构建一个APK都有与之关联的构建类型(Build Type),所以APK总是有两个(或者更多)配置:compile\Compile。创建一个构建类型(Build Type)会自动创建一个基于其名称的新配置。如果debug版本需要使用一个自定义的库(例如提交崩溃信息),但release版本不需要,或者它们依赖于不同版本的相同库时,这会非常有用(查看Gradle文档了解版本冲突的处理方式的细节)。

3.1.2 远程包(Remote artifacts)

Gradle支持从Maven和Ivy仓库获取依赖包。首先必须在列表中添加仓库,然后必须在依赖中声明是从Maven或者Ivy获取包。

repositories {
    jcenter()
}

dependencies {
    compile 'com.google.guava:guava:18.0'
}

android {
    ...
}

注意:jcenter()是指定仓库的URL的一种简单方式,Gradle支持远程仓库和本地仓库。

注意:Gradle会遵循所有传递的依赖关系。这意味着如果一个依赖有自己的依赖关系,则同时会被拉取下来。

获取更多关于设置依赖关系的信息,请查看Gradle用户指南DSL文档

3.2 多项目设置(Multi project setup)

Gradle项目也可以通过使用多项目配置来依赖于其他Gradle项目。多项目配置通常是通过在项目根目录下建立子目录来保存所有项目。例如以下结构:

MyProject/
+ app/
+ libraries/
    + lib1/
    + lib2/

我们可以定义三个项目,Gradle将根据以下名称来引用:

:app
:libraries:lib1
:libraries:lib2

每个项目都拥有自己的build.gradle文件来声明自己如何构建。另外,在项目的根目录下会有settings.gradle文件来声明所有项目。文件结构如下:

MyProject/
| settings.gradle
+ app/
    | build.gradle
+ libraries/
    + lib1/
        | build.gradle
    + lib2/
        | build.gradle

setting.gradle文件的内容非常简单,其中定义了那个目录是确切的Gradle项目:

include ':app', ':libraries:lib1', ':libraries:lib2'

其中:app项目依赖于其他项目,所以通过以下依赖配置进行声明:

dependencies {
    compile project(':libraries:lib1')
}

更多关于多项目设置的信息查看这里

3.3 库项目(Library projects)

在上一节多项目设置(Multi project setup)中,:libraries:lib1:libraries:lib2可以是java项目,:appAndroid项目则引用它们的jar包输出。然而,如果你想要共享代码可以访问Android APIs或者使用Android类型的资源,那么这些库就不能使用常规的Java项目,必须使用Android库项目。

3.3.1 创建库项目(Creating a Library Project)

一个库项目跟常规的Android项目很类似,只有一小部分区别。由于构建库与构建应用有差别,所以引用的是不同的插件。两种插件内部使用了大量相同的代码,都是引用相同的com.android.tools.build.gradlejar包。

buildscript {
    repositories {
        jcenter()
    }

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

apply plugin: 'com.android.library'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.1"
}

这些代码创建了一个使用23版本API编译的库项目。源码集合(SourceSets)、构建类型(build types)及依赖关系(dependencies)的处理方式与应用项目一致,也可以使用相同方式来自定义。

3.3.2 项目与库项目之间的差别(Differences between a Project and a Library Project)

一个库项目的输出文件是.aar包(Android归类文件)。他是编译代码(jar包文件及本地.so库文件)及资源(manifest,res,assets)的集合。库项目同样可以独立于应用来生成一个的测试APK来测试。由于使用了相同的锚任务(assembleDebugassembleRelease),所以在命令行中构建项目并无不同。至于其他方面,库项目的表现与应用项目一致,都有构建类型(build types)和产品标识(product flavors)(下文会提及),也可以生成多个版本的aar文件。需要注意的是,构建类型(Build Type)的大部分配置不会作用于库项目,但是你可以根据库项目的内容是否需要用于项目或者测试,通过自定义的源码集合(SourceSet)来变更。

3.3.3 引用一个库(Referencing a Library)

引用一个库与引用其他项目的方式一致:

dependencies {
    compile project(':libraries:lib1')
    compile project(':libraries:lib2')
}

注意:如果你引用了多个库,那么引用顺序是很重要的。这与在旧构建系统中,project.properties文件中的依赖关系的顺序一样重要。

3.3.4 库的发布(Library Publication)

默认情况下,一个库只发布release变种(variant)。这个变种(variant)会作用于所有引用该库的项目,而忽略了项目本身设置的变种(variant)类别。我们正致力于消除由于Gradle限制而导致的这种临时限制情况。当然你也可以控制发布哪个变种(variant):

android {
    defaultPublishConfig "debug"
}

需要注意的是这个发布配置的名称必须使用完整的变种(variant)名称,Releasedebug只能在没有产品标识(product flavors)时使用。如果你想更换默认的发布变种(variant)为某个标识变种(variant),你需要这样写:

android {
    defaultPublishConfig "flavor1Debug"
}

发布库的所有变种(variant)也是可行的。我们正在计划允许使用这种正常的项目与项目之间的依赖(比如之前展示的示例),但由于Gradle的限制,现在还无法实现(我们正在努力解决这些问题)。默认未开启发布所有变种(variant),以下代码片段开启该特性:

android {
    publishNonDefault true
}

你必须意识到,发布多个变种(variant)意味着发布多个变种(variant)的多个aar文件,而不是包含多个变种(variant)的单个aar文件,每个aar文件只包含单个变种(variant)。发布一个变种(variant)意味着aar文件会作为Gradle项目的输出文件。无论是发布到Maven仓库或者用于依赖于该库项目的项目,都会使用到该文件。

Gradle有个默认工件(artifact)的概念,以下代码是使用到的其中一个:

dependencies {
    compile project(':libraries:lib2')
}

如果要依赖于其他发布工件(artifact),你需要具体指明使用哪个:

dependencies {
    flavor1Compile project(path: ':lib1', configuration: 'flavor1Release')
    flavor2Compile project(path: ':lib2', configuration: 'flavor2Release')
}

重点:注意发布配置必须使用一个完整的变种(variant),并且要包含构建类型(build type),而且也需要像上面一样引用。

重点:当启用非默认发布时,maven发布插件将这些附加变种(variant)作为扩展包发布。这意味着发布到maven仓库不是真正兼容的。你应该发布一个单一版本到仓库或者使所有配置发布项目间依赖关系。