1. Android 应用的构建过程
首先所有的资源文件都会被编译,并且在 R 文件中引用。然后 Java 代码被编译,之后通过 dex 工具转换成 dalvik 字节码。最后这些文件会被打包成一个 Apk 文件。
通过 Gradle 可以很方便的执行 上述繁琐的工作过程,下面让我们走进 Gradle 的世界。
2. Gradle 基础
Gradle 构建脚本的书写基于 Groovy 的领域专用语言(DSL),Groovy 是一种基于 Java 虚拟机的动态语言。
在 Gradle 中,最重要的两个概念是项目和任务。每一次构建都包括至少一个项目,每一个项目又包括一个或多个任务。
每个 build.gradle 文件代表着一个项目,任务定义在构建脚本里。当初始化构建过程时,Gradle 会基于 build 文件组装项目和任务对象。一个任务对象包含一系列动作对象,这些动作对象之后会按照顺序执行。
Gradle 构建通常有以下三个阶段:
-
初始化
项目实例会在该阶段被创建。如果一个项目有多个模块,并且每一个模块都有其对应的 build.gradle 文件,那么就会创建多个项目实例。
-
配置
在该阶段,构建脚本会被执行,并为每个项目实例创建和配置任务。
-
执行
在该阶段,Gradle 将决定哪个任务会被执行。哪些任务被执行取决于开始该次构建的参数配置和该 Gradle 文件的当前目录。
每一个基于 Gradle 构建的项目,都应该至少有一个 build.gradle 文件。Android 的构建文件中,有一些元素是必需的:
buildscript {
repositories {
google()
jcenter() // JCenter 库被配置为整个构建过程的依赖仓库
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1' // Android 插件
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
这就是实际构建配置的地方。
构建脚本代码块在 Android 构建工具上定义了一个依赖,这就是 Android 插件的来源。Android 插件提供了构建和测试应用所需要的一切。每一个 Android 项目都应该申请该插件:
apply plugin: 'com.android.application'
如果构建一个依赖库,需要声明:
com.android.library
Gradle 的优点是约定优于配置。
Gradle 使用一个叫做源集(source set)的概念。一个源集就是一组源文件,它们会被一起执行和编译。
对于 Android 项目而言,main 就是一个源集,它包含了所有的源代码和资源,是应用程序默认版本的源集。
为 Android 应用编写测试代码时,可以把所有的测试相关的代码都放在一个独立的源集中,该源集被叫做 androidTest,只包含测试代码。
Gradle Wrapper 为微软的 Windows 操作系统提供了一个 batch 文件,为其他操作系统提供了一个 shell 脚本。当运行这段脚本时,需要的 Gradle 版本会被自动下载(如果不存在)和使用。为了方便起见,每个新的 Android 项目都会包含 Gradle Wrapper。
3. 运行基本构建任务
在 Android Studio 的 terminal 窗口执行 Gradle Wrapper 命令。
-
gradlew tasks
打印出所有可用的任务列表。如果添加 --all 参数,将获得每个任务对应依赖的详细介绍。
-
gradlew assembleDebug
这个任务会为这个应用创建一个 dubug 版本的 APK。
除了 assembel 外,还有其他三个基本任务。
Check: 运行所有的检查,通常意味着在一个连接的设备或模拟器上运行测试。
Build: 触发 assemble 和 check。
Clean: 清除项目的输出。
4. Gradle 基本文件
项目中 Gradle 文件的位置:
build.gradle 和 settings.gradle 文件位于项目的根目录。
另一个 build.gradle 则在 Android app 模块内被 创建。
4.1 settings 文件
对于一个只包含一个 Android 应用的新项目来说,settings.gradle 应该是这样的:
include ':app'
settings 文件在初始化阶段被执行,并且定义了哪些模块应该包含在构建内。
4.2 顶层构建文件文件
在项目中,所有模块的配置参数都应在顶层 build.gradle 文件中配置。默认代码如下:
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
实际构建配置在 buildscript 代码块内。
dependencies 代码块用于配置构建过程中的依赖包。默认情况下,唯一被定义的依赖包是 Gradle 的 Android 插件。
allprojects 代码块可用来声明那些需要被用于所有模块的属性。
4.3 模块的构建文件
模块层的 build.gradle 文件的属性只能应用在 Android app 模块,它可以覆盖顶层 build.gradle 文件的任何属性。
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.example.wyj.gradlestudytest"
minSdkVersion 15
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}
- 插件
第一行用到了 Android 应用插件,该插件在顶层构建中被配置成依赖。谷歌的 Android 工具团队负责 Android 插件的编写和维护 ,并提供构建、测试和打包 Android 应用以及依赖项目的所有任务。
- Android
在构建文件中,占比最大的是 android 代码块。该代码块包含了全部的 Android 特意有置。defaultConfig 代码块用于配置应用的核心属性。
compileSdkVersion(必须):编译应用 Android API 的版本
buildToolsVersion(必须:构建工具及编译器的版本号
buildTypes 代码块可用来定义如何构建和打包不同构建类型的应用。
- 依赖包
依赖代码块是标准 Gradle 配置的一部分(这就是其放在 android 代码块之外的原因)。其定义了一个应用或依赖项目的所有依赖包。