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的语言去写你自己的插件。
工程和任务
project和task是Gradle中两个最重要的概念。每个构建由至少一个project组成,每个project包含一个或多个tasks。每个build.gradle
文件代表一个project,tasks声明在构建脚本中。初始化构建过程时,Gradle基于构建文件收集(assembles)Project
和Task
对象。一个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。需要提供的必需属性只有compileSdkVersion
和buildToolsVersion
。
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运行
assemble
和check
- clean清理工程的output
我们将在第二章详细讨论这些任务。
从Eclipse迁移
本节略过