上一篇(Groovy(一): build.gradle为何物? )主要是我们熟悉的build.gradle,项目开发基本上够用了,如果还想深入了解下来龙去脉,可以继续学习(Gradle for Android 下载本书)
如果你也像我一样从eclipse换到as来进行项目开发的,如果对其中的gradle比较感兴趣,那么就跟随我一起来学习下:
一.从 Gradle 和 AS 开始
如果你想创建一个Android project基于gradle,那么你必须写一个构建脚本,这个文件通常称之为build.grade,你可能已经觉察到了,当我们查看这一脚本,gradle会为我们提供很多默认的配置以及通常的默认值,而这极大的简化了我们的工作,例如ant和maven,使用他们的时候,我们需要编写大量的配置文件,而这很恶心。而gradle得默认配置,如果你需要使用自己的配置,完全可以简单的去重写他们就好。
Gradle脚本不是像传统的xml文件那样,而是一种基于Groovy的动态DSL,而Groovy语言是一种基于jvm的动态语言。
你完全不用担心,你在使用gradle的时候,还需要去学习Groovy语言,该语言很容易阅读,并且如果你已经学习过java的话,学习Groovy将不会是难事,如果你想开始创建自己的tasks和插件,那么你最好对Groovy有一个较深的理解,然而由于其基于jvm,所以你完全可能通过纯正的java代码或者其他任何基于jvm的语言去开发你自己的插件,关于插件开发,我们后续将会有相关介绍。
Project和tasks
在grade中的两大重要的概念,分别是project和tasks。每一次构建都是有至少一个project来完成,所以Android studio中的project和Gradle中的project不是一个概念。每个project有至少一个tasks。每一个build.grade文件代表着一个project。tasks在build.gradle中定义。当初始化构建进程,gradle会基于build文件,集合所有的project和tasks,一个tasks包含了一系列动作,然后它们将会按照顺序执行,一个动作就是一段被执行的代码,很像Java中的方法。
构建的生命周期
一旦一个tasks被执行,那么它不会再次执行了,不包含依赖的Tasks总是优先执行,一次构建将会经历下列三个阶段:
1.初始化阶段:project实例在这儿创建,如果有多个模块,即有多个build.gradle文件,多个project将会被创建。
2. 配置阶段:在该阶段,build.gradle脚本将会执行,为每个project创建和配置所有的tasks。
3. 执行阶段:这一阶段,gradle会决定哪一个tasks会被执行,哪一个tasks会被执行完全依赖开始构建时传入的参数和当前所在的文件夹位置有关。
build.gradle的配置文件
基于grade构建的项目通常至少有一个build.gradle,那么我们来看看Android的build.gradle:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
这个就是实际构建开始的地方,在仓库地址中,我们使用了JCenter,JCenter类似maven库,不需要任何额外的配置,grade还支持其他几个仓库,不论是远程还是本地仓库。
构建脚本也定义了一个Android构建工具,这个就是Android plugin的来源之处。Android plugin提供了所有需要去构建和测试的应用。每个Android应用都需要这么一个插件:
apply plugin: 'com.android.application'
插件用于扩展gradle脚本的能力,在一个项目中使用插件,这样该项目的构建脚本就可以定义该插件定义好的属性和使用它的tasks。
注意:当你在开发一个依赖库,那么你应该使用’com.android.library’,并且你不能同时使用他们2个,这将导致构建失败,一个模块要么使用Android application或者Android library插件,而不是二者。
当使用Android 插件的时候,Android标签将可以被使用,如下所示:
android {
compileSdkVersion 25
buildToolsVersion "25.0.3"
}
grade项目通常在根文件夹中包含一个build.gradle,使用的代码在app这个文件夹中,这个文件夹也可以使用其他名字,而不必要定义为app,例如当你利用Android studio创建一个project针对一个手机应用和一个Android wear应用的时候,模块将被默认叫做application和wearable。
gradle使用了一个叫做source set的概念,官方解释:一个source set就是一系列资源文件,其将会被编译和执行。对于Android项目,main就是一个source set,其包含了所有的资源代码。当你开始编写测试用例的时候,你一般会把代码放在一个单独的source set,叫做androidTest,这个文件夹只包含测试。
开始使用Gradle Wrapper
grade只是一个构建工具,而新版本总是在更迭,所以使用Gradle Wrapper将会是一个好的选择去避免由于gradle版本更新导致的问题。Gradle Wrapper提供了一个windows的batch文件和其他系统的shell文件,当你使用这些脚本的时候,当前gradle版本将会被下载,并且会被自动用在项目的构建,所以每个开发者在构建自己app的时候只需要使用Wrapper。所以开发者不需要为你的电脑安装任何gradle版本,在mac上你只需要运行gradlew,而在windows上你只需要运行gradlew.bat。
你也可以利用命令行./gradlew -v来查看当前gradle版本。下列是wrapper的文件夹:
myapp/
├── gradlew
├── gradlew.bat
└── gradle/wrapper/
├── gradle-wrapper.jar
└── gradle-wrapper.properties
可以看到一个bat文件针对windows系统,一个shell脚本针对mac系统,一个jar文件,一个配置文件。配置文件包含以下信息:
Wed Jun 14 16:22:36 CST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https://services.gradle.org/distributions/gradle-3.3-all.zip
你可以改变该url来改变你的gradle版本。
使用基本的构建命令
使用你的命令行,导航到你的项目,然后输入:
$ ./gradlew tasks
All tasks runnable from root project
Android tasks
androidDependencies - Displays the Android dependencies of the project.
signingReport - Displays the signing info for each variant.
sourceSets - Prints out all the source sets defined in this project.Build tasks
assemble - Assembles all variants of all applications and secondary packages.
assembleAndroidTest - Assembles all the Test applications.
assembleDebug - Assembles all Debug builds.
这一命令将会列出所以可运行的tasks,你也可以添加–all参数,来查看所有的task。当你在开发的时候,构建项目,你需要运行assemble task通过debug配置:
$ gradlew assembleDebug
该任务将会创建一个debug版本的app,同时Android插件会将其保存在MyApp/app/build/ outputs/apk目录下。
除了assemble,还有三个基本的命令:
- check 运行所以的checks,这意味着运行所有的tests在已连的设备或模拟器上。
- build 是check和assemble的集合体。
- clean 清楚项目的output文件。
在grade文件中配置,如果你有任何依赖的jar包,你需要告诉gradle它在哪儿,假设jar包会在一个叫做libs的文件夹内,那么你应该这么配置:
dependencies {
compile fileTree(dir: ‘libs’, include: [‘*.jar’])
}
该行意为:将libs文件夹中所有的jar文件视为依赖包。
当然,对于上述的命令,在android studio中是可以直接查看的:
二.理解Gradle脚本
setting.gradle解析
当你的app只有一个模块的时候,你的setting.gradle将会是这样子的:
include ':app'
setting.gradle文件将会在初始化时期执行,关于初始化时期,可以查看上一篇博客,并且定义了哪一个模块将会被构建。举个例子,上述setting.gradle包含了app模块,setting.gradle是针对多模块操作的,所以单独的模块工程完全可以删除掉该文件。在这之后,Gradle会为我们创建一个Setting对象,并为其包含必要的方法,你不必知道Settings类的详细细节,但是你最好能够知道这个概念。
根目录的build.gradle
该gradle文件是定义在这个工程下的所有模块的公共属性,它默认包含三个方法:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
buildscript方法是定义了全局的相关属性,repositories定义了jcenter作为仓库。一个仓库代表着你的依赖包的来源,例如maven仓库。dependencies用来定义构建过程。这意味着你不应该在该方法体内定义子模块的依赖包,你仅仅需要定义默认的Android插件就可以了,因为该插件可以让你执行相关Android的tasks。
allprojects方法可以用来定义各个模块的默认属性,这里是声明了所有project默认的仓库源。
task clean声明了一个任务,任务名叫clean(也可以改为其它),任务类型是Delete(也可以是Copy),就是每当修改settings.gradle文件后点击同步,就会删除rootProject.buildDir下的文件(实际上我看到的效果是清除了External Libraries里的包,然后又添加了一次)。
模块内的build.gradle
模块内的gradle文件只对该模块起作用,而且其可以重写任何的参数来自于根目录下的gradle文件。该模块文件应该是这样:
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.gradleforandroid.gettingstarted"
minSdkVersion 14
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile
('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.0'
}
plugin
该文件的第一行是Android应用插件,该插件我们前面已经介绍过,其是google的Android开发团队编写的插件,能够提供所有关于Android应用和依赖库的构建,打包和测试。
android
该方法包含了所有的Android属性,而唯一必须得属性为compileSdkVersion和buildToolsVersion:
compileSdkVersion:编译该app时候,你想使用到的api版本。
buildToolsVersion:构建工具的版本号。
构建工具包含了很多实用的命令行命令,例如aapt,zipalign,dx等,这些命令能够被用来产生多种多样的应用程序。你可以通过sdk manager来下载这些构建工具。
defaultConfig方法包含了该app的核心属性,该属性会重写在AndroidManifest.xml中的对应属性。
defaultConfig {
applicationId "com.gradleforandroid.gettingstarted"
minSdkVersion 14
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
第一个属