Gradle for Android(一) 使用Gradle和Android Studio

Google引入Gradle和Android Studio时,希望更容易的去重用代码、创建构造变体和配置、自定义构造过程。除此之外,他们想要好的IDE集成,但是又不想让构建系统依赖IDE。使用命令行,或者在持续集成的服务器上运行Gradle,将和在Android Studio中运行Gradle得到同样的结果。

在本书中,我们会偶尔涉及到Android Studio,因为它提供了一个简单的途径来配置工程、处理变更等等。如果你还没有安装Android Studio,你可以在http://developer.android.com/sdk/index.html下载

本章将涵盖以下内容:

  • 初识Android Studio
  • 了解Gradle基础
  • 创建一个新工程
  • 开始使用Gradle Wrapper
  • 迁移Eclipse工程(略过)

Adroid Studio

Google在2013年5月发布了Android Studio的早期预览版,支持Gradle。Android Studio以JetBrains公司的IntelliJ IDEA为基础,在设计上包含了Android独特的风格。它是免费的,支持Linux、Mac OS X和Windows系统。

相对于Eclipse,Android Studio拥有改进的UI设计,更好的内存监控,更友好的编辑器,对Android特有的一些问题发出警告,以及其他许多针对Android开发者的特征。除IntelliJ IDEA已有的工程视图和包视图,它有独特的针对Android工程的工程结构视图。这个独特的视图使用一种便捷的方式对Gradle脚本、drawables和其他资源进行分组。Android Studio v1.0稳定版甫一发布,Google就停止了对ADT的支持,推荐开发者们切换到Adroid Studio。这意味着Goole将再也不会为Eclipse提供新特性,并且所有的IDE相关的工具开发将集中在Android Studio身上。如果你还在使用Eclipse,是时候去更换开发工具了。

更新

Android Studio有四个更新渠道:

  • Canary是最前沿的更新渠道,但可能有bug
  • Dev或多或少每月一更新
  • Beta功能完全更新,但可能有bug
  • Stable是默认的渠道,新特性经过了完全的测试,很少有bug

默认Android Studio每次启动都会检查更新,若有更新会及时通知你。

在你第一次启动Android Studio的时候,它会引导你设置环境变量,确保你有最新的Android SDK和必要的Google repositories。它还会让你选择去创建一个模拟器,以便运行你的应用。

了解Gradle基础

为了使Android工程能够使用Gradle进行构建,你需要配置构建脚本。脚本名称必须是build.gradle,这是约定俗成的。在我们学习基础的时候,你会注意到一件事情,Gradle在配置上更倾向于约定,通常会为设置和属性提供默认值。这就使得我们可以使用更少的配置来开发项目,相对于Ant或者Maven系统要更加简单。我们不必绝对遵守这些约定俗成的东西,因为在需要的时候它们可以被覆写。

Gradle脚本语言并非使用传统的XML,而是使用了基于Groovy的domain-specific language(DSL),一种运行在JVM上的动态语言。Gradle团队认为使用基于动态语言的、声明式的、DSL风格的方式,比Ant使用的更加程式化、自由浮动的风格,或者很多其他构建系统使用的基于XML的方式具有更大的优势。

这并不意味着在开始你的构建脚本之前,你需要先去了解Groovy。它很容易阅读,并且如果你已经会使用Java,学习起来将得心应手。如果你想去创建你自己的任务和插件(我们会在后续的章节讨论),你最好对Groovy有个深入的理解。不管怎样,因为它是基于JVM的,你可以使用Java或其他任何基于JVM的语言去写你自己的插件。

工程和任务

projecttask是Gradle中两个最重要的概念。每个构建由至少一个project组成,每个project包含一个或多个tasks。每个build.gradle文件代表一个project,tasks声明在构建脚本中。初始化构建过程时,Gradle基于构建文件收集(assembles)ProjectTask对象。一个Task对象由一系列的Action对象构成,它们将顺序执行。一个Action对象是一个代码块,类似Java中的方法。

构建的生命周期

以最简单的方式来看,Gradle构建的执行过程就是执行task的actions,这个task又依赖于其他的task。为了简化构建过程,构建工具会创建一个工作流的动态模型,就像一个有向无循环图。这意味着所有的task将会一个接一个执行,并且不会循环。一旦一个task被执行,它不会再次被执行。没有依赖的task先于其他task执行。依赖图在构建的配置期生成。一个Gradle构建有3个时期:

  • Initialization:创建Project实例。如果有多个module,每个都有自己的build.gradle文件,那么将会创建多个Project
  • Configuration:执行构建脚本,为每一个Project对象创建和配置所有的tasks。
  • Execution:Gradle将决定哪些tasks被执行。哪些任务被执行取决于启动构建时传入的参数以及当前所在目录。

构建配置文件(build.gradle)

为使Gradle能够构建工程,必须要有一个build.gradle文件。该文件只有很少的必需元素:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.2.3'
    }
}

这里将为最终的构建进行配置。在repositories块中为构建脚本配置了JCenter仓库作为一个依赖源。JCenter是一个预置的Maven仓库,不需要额外的配置,Gradle已经为你配置好了。Gradle有几个仓库可以直接使用,而且添加你自己的仓库也非常简单,不管是本地的还是远程的。

构建脚本块同时定义了一个Android构建工具的依赖,有了它就可以使用Android插件了。Android插件提供构建和测试应用的所有东西。每一个Android工程需要引入以下代码来使用Android插件:

apply plugin 'com.android.application'

插件用来扩展Gradle构建脚本的能力。在工程中应用插件,可以使构建脚本使用在插件中声明的属性和任务。

如果你正在构建一个library,你需要引用:

apply plugin 'com.android.library'

你不可以在一个工程中同时引用这两个插件,否则会导致构建错误。一个module只能是Android application或者Android library之一。

在使用Android插件时,会配置Android特有的规则,创建只适用于Android的tasks。在下面的代码片段中,android块可以被声明和配置:

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"
}

构建脚本中的Android特有的部分在这里配置。Android插件提供了一个为Android定制的DSL。需要提供的必需属性只有compileSdkVersionbuildToolsVersion

build.gradle还有很多可定制的属性。我们将在第2张讨论最重要的属性。

工程结构

与Eclipse工程相比,文件夹结构发生了很大改变。就像前面提到的,Gradle在配置上倾向于约定俗成,这也体现在文件夹结构上。

下面是Gradle期望的文件夹结构:

MyApp
├── build.gradle
├── settings.gradle
└── app
    ├── build.gradle
    ├── build
    ├── libs
    └── src
        └── main
            ├── java
            │   └── com.package.myapp
            └── res
                ├── drawable
                ├── layout
                └── etc.

Gradle工程通常在根节点有一个额外的级别。这使得以后添加其他模块变得简单。所有应用的源代码放在app文件夹下。这个文件夹也是默认的模块的名称。默认的模块并非一定要命名为app。举个例子,如果你使用Android Studio创建一个同时包含mobile app和Android Wear smartwatch app的工程时,模块名称默认分别是application和wearable。

Gradle使用了source set的概念。Gradle的官方文档将source set解释为“一个可以同时被编译和执行的,包含源文件的集合”。对于一个Android工程,main是默认的app模块的source set,包含全部源代码和资源。在你开始为Android app写测试代码的时候,你将会把所有的测试代码写到一个单独的称为androidTest的source set中。

下面是Android app中最重要的文件夹的一个综述:

目录 描述
/src/main/java app源代码
/scr/main/res app相关的资源,如drawables、layouts、strings等
/libs 外部库,如.jar文件或者.arr文件
/build 构建过程的输出目录

创建一个新工程

讲述如何使用Android Studio开始一个新工程,本节略过。

使用Gradle Wrapper

Gradle是一个不断开发的工具,新的版本可能会打破向后兼容性。使用Gradle Wrapper是避免问题的好方法,并确保构建是可复制的。

Gradle Wrapper在Windows系统中提供了一个批处理文件,在其他操作系统中提供了一个shell脚本。在你运行脚本的时候,所需的Gradle版本会被下载下来(如果还未下载的话),并自动用于构建。其背后的思想是每个需要构建app的开发者或者自动构建系统只需要运行wrapper就可以了,剩下的工作wrapper会处理。这样在开发者的机器或者构建服务器上就不必手动安装相应版本的Gradle。所以,我们建议将wrapper添加到你的版本控制系统中。

运行Gradle Wrapper和直接运行Gradle没有太大的差别。你只需要在Linux和Mac OS X上运行gradlew,在Windows系统上运行gradlew.bat,来替代gradle命令

获取Gradle Wrapper

为了方便,每一个新建的Android工程都包含Gradle Wrapper,所以当你新建一个工程的时候,你根本不需要去做任何事情来获取所需的文件。当然了,你也可以在你的电脑上手动安装Gradle,并在工程中使用它,但Gradle Wrapper可以做同样的事情,并保证使用正确版本的Gradle。即使在Android Studio之外使用Gralde,也没有理由不去使用Wrapper。

你可以切换到工程目录下,在终端(Linux、Mac OS X)运行./gradlew -v或者在命令行(Windows)运行gradlw.bat -v来检查Gradle Wrapper是否可用。运行这个命令会显示你的Gradle版本和一些关于你的配置的信息。如果你在转换一个Eclipse工程,默认Wrapper是不可用的。这种情况下,你可以使用Gradle来生成它,但前提是你要安装Gradle。

在你下载并将Gradle添加到环境变量之后,可以用下面代码创建一个build.gralde文件:

task wrapper(type: Wrapper) {
    gradleVersion = '2.4'
}

接下来运行gradle wrapper来生成Wrapper文件。

在最近的Gradle版本中,默认包含这个任务。你可以使用--gradle-version参数来指定版本:

$ gradle wrapper --gradle-version 2.4

如果你不指定版本号,将使用task所运行的Gradle版本来配置warpper。

下面是wrapper task所生成的所有文件:

myapp/
├── gradlew
├── gradlew.bat
└── gradle/wrapper/
    ├── gradle-wrapper.jar
    └── gradle-wrapper.properties

可以看到,Gradle Wrapper由三部分组成:

  • 一个Windows上的批处理文件或者Linux/Mac OS X上的shell脚本
  • 一个批处理文件或者shell脚本使用的JAR包
  • 一个properties文件

gradle-wrapper.properties文件包含配置信息,并决定Gradle版本:

#Sat May 30 17:41:49 CEST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip

你可以修改distributionUrl来自定义Gradle地址。这意味着你使用的每个app或者library可以使用不同的Gradle地址,所以在运行wrapper之前一定要确认这些属性是否安全。

在工程所使用的Gradle不是最新的时候,Android Studio会友好的显示一个通知,并建议是否自动升级到最新版本。Android Studio会修改gradle-wrapper.properties文件的配置,并触发一次构建,这样最新版本就会下载下来。

运行基本的构建任务

切换到工程目录,在终端或者命令行运行tasks命令:

$ gradlew tasks

这会打印出所有可用的任务。加上--all参数,会显示更详细的任务之间的依赖关系。

在Windows系统,你需要运行gradlew.bat;在Linux/Mac OS X系统,你需要运行./gradlew,为了简洁,本书只写gradlew

当你在开发时去构建工程,使用debug配置去运行assemble任务:

$ gradlew assembleDebug

这个任务会创建一个debug版本的APK。Android插件默认将APK保存在MyApp/app/build/outputs/apk目录。

简短的任务名称
为了避免在终端输入过多字符,Gradle提供了简短的驼峰式任务名称作为快捷方式。比如,你可以输入gradlew assDeb来执行assembleDebug,甚至输入gradlew aD
需要注意的是,只有当驼峰式表示法唯一的时候才可以这样写。如果其他的任务有相同的简写,这样书写方式将不会工作。

除了assemble,还有另外3个基本任务:

  • check运行所有的任务,通常用来在真机或者模拟器上进行测试。
  • build运行assemblecheck
  • clean清理工程的output

我们将在第二章详细讨论这些任务。

从Eclipse迁移

本节略过

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

推荐阅读更多精彩内容