Google 原来使用 Ant 作为它的构建系统。但在使用了 Android Studio 后却确定使用 Gradle。

新构建系统的要求

  • 容易重建代码和资源
  • 容易创建不同程序的变体,无论是要创建多个发布版本还是为同一个程序创建不同的属性
  • 易于配置,扩展和定制构建流程
  • IDE集成

为什么是 Gradle

gradle 是一个高级的构建系统,同时允许工具通过插件创建定制化构建逻辑。

下面是我们使用 Gradle 的一些原因:

  • 使用 Domain Specific Language 来描述和控制构建逻辑
  • 构建文件是基于 Groovy的,而且通过 DSL 支持装饰元素(例如 dependencies,configurations) 还可以使用代码来操作 DSL 元素来提供定制逻辑。
  • 通过 Maven 和/或 Ivy 来管理依赖关系
  • 非常灵活, 允许使用最佳实践但不强制使用唯一方式来完成事项。
  • 插件可以提供其特定 DSL 和他们特定 的 API 给构建文件使用。
  • 良好的 API 集成

版本要求

  • Gradle 1.10 或 1.11 或 1.12 + plugin 0.11.1
  • SDK 构建工具 19.0.0以上

基本工程

一个 Gradle 工程会在工程的根目录创建一个叫做 build.gradle 的文件

简单地构建文件

最简单的 Java 工程构建文件 build.gradle 如下

apply plugin: 'java'

这个文件申请了 java 插件,这个插件已经内置在 Gradle 中。这个插件提供构建和测试 Java 程序的所有东西。

而最简单地 Android 工程就是这样的

buildscript {
    repositories {
        mavenCentral()
    }

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

    apply plugin: 'android'

    android {
        compileSdkVersion 19
        buildToolsVersion "19.0.0"
    }
}

这个 Android 构建文件有3个主要区域

buildscript {...} 配置了驱动构建的代码 在这个例子中。文件声明了使用 Maven Central repository。还声明了其 repository 依赖于包含 Android 插件的 gradle

注意:这个文件只会影响运行构建的代码,而不是项目。项目需要另外的 build.gradle

然后 android 插件区域就像之前 Java 插件那样。

最后 android { ... } 配置了构建Android需要的参数。只是 Android DSL 的入口。 默认只需要编译目标和构建工具的版本。由 compileSdkVersionbuildToolsVersion 来定义。

重要:你只需要申请 android 插件而不需要申请 Java 插件,否则会报错。

注意:你还需要 local.properties 来设定 SDK 的位置。 或者你可以设置 ANDROID_HONE 环境变量来设置 SDK 位置。

工程结构

基本的工程开始自两个叫做 source sets 的文件夹。主代码目录和测试目录。

src/main/
src/androidTest/

在 main 目录有 Java 源码目录和资源目录

Java/
resources/

对于 Android 插件,还有额外的文件和目录

AndroidManifest.xml
res/
assets/
aidl/
rs/
jni/

注意: src/androidTest/AndroidManifest.xml 不需要,因为它会自动创建。

配置结构

当默认的配置不适用的时候,我们可以配置它。根据 Gradle 文档,重新配置 Java 工程的 sourceSets 可能会这样的:

sourceSets {
    main {
        java {
            srcDir 'src/java'
        }
        resources {
            srcDir 'src/resources'
        }
    }
}

为了替换默认的源目录,你可能想改使用 srcDirs,这个属性可以使用路径的集合。下面显示一种使用 objects 不同的方法。

sourceSets {
    main.java.srcDirs = ['src/java']
    main.resources.srcDirs = ['src/resources']
}

想了解更多信息,可以参加 Gradle 文档关于 Java 插件部分

Android 插件使用了类似的语法。因为它使用特定的 sourceSets,这已经在 android object 中完成了。 下面是例子。使用旧的工程结构和重映射 androidTest 的 sourceSet 到 tests 目录:

android {
    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }
        androidTest.setRoot('tests')
    }
}

注意:因为旧的结构把所有源文件放到同一个目录。我们需要重定向所有 sourceSet 组件到 src 目录。 注意:setRoot() 把整个 sourceSet 移动到新的目录。这里把 src/androidTest/* 移动到 tests/* 这些是 Android 特有的特性,在 Java sourceSets 不会生效。

构建任务

一般任务