第二章 基本自定义构建
一、理解 Gradle 文件
当使用 AndroidStudio 创建一个 Android 项目时,会默认生成三个 Gradle 文件。
- settings.gradle
- build.gradle (根目录下)
- build.gradle ( app 下)
1. settings.gradle 文件用途
settings 文件在初始化阶段被执行,并且定义了哪些模块应该包含在构建内。一个简单的 Android 应用中,settings 文件的内容应该是: include ':App'
。
单模块项目并不一定需要 settings 文件,但是多模块项目必须要有 settings 文件,否则 Gradle 不知道哪个模块应该包含在构建内。
2. 顶层构建文件:build.gradle (根目录下)
在项目中,所有模块的配置参数都应在顶层 build.gradle 文件中配置。默认情况下其包含如下两个代码块:
//构建脚本,在这里配置所有模块的配置参数
buildscript {
ext.kotlin_version = '1.2.70'
repositories {
//项目依赖的maven库
//模块的 dependecies 都是去该库中下载的依赖包
jcenter()
google()
}
dependencies {
//当前项目的依赖(也就是所有模块都会具有如下依赖)
classpath 'com.android.tools.build:gradle:3.1.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
jcenter()
}
}
3. 模块的构建文件:build.gradle (app目录下)
模块层的 build.gradle 文件的属性只能应用在 Android App 模块(每个模块都有自己的构建文件),它可以覆盖顶层 build.gradle 文件的任何属性。该模块的构建文件示例如下:
// Android 的应用插件,该插件在顶层构建文件中被配置成了依赖,所以模块部分可直接使用
// 该插件由 Google 的工具团队负责编写和维护,并提供构建、测试和打包 Android 应用以及依赖项目的所有任务
apply plugin: 'com.android.application'
//下面两个是使用 Kotlin 所需的插件
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
//此代码块包含了全部 Android 特有的配置,这些配置是在 Android 插件的支持下才能被使用的
android {
compileSdkVersion 28 //必须有的属性:用什么版本来编译 Android 应用
//此代码块用于配置应用的核心属性,可覆盖在 AndroidManifest.xml 文件中对应的条目
defaultConfig {
//该属性覆盖了 AndroidManifest.xml 中的 package,用于多渠道打包
// AndroidManifest.xml 作为应用的唯一标志,并且在 R 资源类中被用作包名
// 不同 applicationId 可以在应用市场被识别为不同的应用
applicationId "zyf.com.studygradle01"
minSdkVersion 19 //最小 SDK 版本
targetSdkVersion 28 //目标 SDK 版本,是要告诉系统,
//该应用已经在某特定Android版本中通过测试,这样操作系统就不必弃用任何向前兼容的行为
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
//此代码块被用来定义如何构建和打包不同构建类型的应用
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
// 依赖代码块
// 是标准 Gradle 配置的一部分,不属于 Android 应用的层面
// 所以被放在 android{} 之外
// 此处定义了一个应用或模块所依赖项目的所有依赖包
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
构建工具包含命令行应用,如 aapt、zipalign、dx 和 renderscript,这些都被用来在打包应用时生成各种中间产物。可以通过 SDK Manager 下载工具。
二、任务入门
要想知道在一个项目中有哪些任务可被使用,则可以运行 gradlew tasks
任务,该命令会打印出所有可用的任务。
1. 基础任务
Gradle 的 Android 插件使用了 Java 基础插件,而 Java 基础插件又使用了基础插件。
- 基础插件定义了 assemble 和 clean 任务。(类似于 interface,就是一个约定,并没有具体实现)
- Java 插件定义了 check 和 builtasks 任务
约定如下:
- assemble:集合项目的输出
- clean:清理项目的输出
- check:运行所有检查,通常是单元测试和集成测试。
- build:同时运行 assemble 和 check
Java 基础插件添加了 源集
的概念。一个源集就是一组源文件,它们会被一起执行和编译。
2. Android 任务
Android 插件扩展了基本任务,并实现了它们的行为。
- assemble:为每个构建版本创建一个 APK
- clean:删除所有的构建内容,例如 APK 文件
- check:运行 Lint 检测,如果 Lint 发现一个问题,则可终止构建
- build:同时运行 assemble 和 check
assemble 任务默认依赖于 assembleDebug 和 assembleRelease ,如果我们添加了更多的构建类型,那么就会有更多的任务。也就是只要执行了 assemble 那么就会构建每一个 buildType
中的构建类型。
Android 插件还新添加了一些任务,下面是一些值得注意的新任务:
- connectedCheck:在连接设备或模拟器上运行测试
- deviceCheck:一个占位任务,专为其他插件在远端设备上运行测试(不是很理解)
- installDebug 和 installRelease:在连接设备或模拟器上安装特定版本
- 所有的 installTasks 都会有 相对应的 uninstall 任务
总结: 通常使用的命令是 gradlew build
该命令实际上是执行了 gradlew check
和 gradlew assemble
。check
会运行 Lint 检查程序是否存在问题,会将警告和错误打印到 app/build/reports
的一个文件中。assemble
就会为每个构建版本创建一个 APK
3. Android Studio

- 也可以通过上图中的选项执行 Gradle 命令
三、自定义构建
自定义构建的方式有很多种,无论我们在构建文件中自定义了什么,都应该始终同步该项目(就是Android Studio 上会弹出的 Sync Now
。
在底层,Android Studio 在执行 Sync Now
时,实际上是运行了 generateDebugSources 任务来生成所需的类。
1. 操纵 manifest 条目
- 可以直接在构建文件( build.gradle )中配置如下信息:
- applicationId
- minSdkVersion
- targetSdkVersion
- versionCode
- versionName
- testApplicationId:针对 instrument 测试 APK 的 applicationId
- testInstrumentationRunner:JUnit 测试运行器的名称,被用来运行测试。
- signingConfig
- proguardFile 和 proguardFiles
- 也可以使用 Android Studio 提供的图形化配置界面(会覆盖掉 build.gradle )
-
image
-
2. BuildConfig 和资源
自 SDK 版本升级到 17 之后,构建工具都会生成一个叫做 BuildConfig 的类,该类包含一个按照构建类型 BuildType
设置值的 DEBUG
常量。可以通过 Gradle 来扩展该文件,这样在 debug 和 release 时,就可以拥有不同的常量。
这些常量可用于切换功能或设置服务器 URL :
android {
compileSdkVersion 28
defaultConfig {
applicationId "zyf.com.studygradle01"
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
debug{
buildConfigField("String","API_URL","\"http://test.example.com/api\"")
buildConfigField("Boolean","LOG_HTTP_CALLS","true")
}
release {
buildConfigField("String","API_URL","\"http://example.com/api\"")
buildConfigField("Boolean","LOG_HTTP_CALLS","false")
}
}
}
- android{} 中包含的是 Android 特有的配置
- buildTypes{} 中包含的是 不同的构建版本:调试版与发布版
- buildConfigField:在 BuildConfig 类中生成一个属性,接受三个字符串参数
- 参数一:该属性的类型 String
- 参数二:该属性的属性名 API_URL
- 参数三:该属性的值 \"http://test.example.com/api"
- 生成结果应该为:String API_URL = "http://test.example.com/api"
- 参数三中接受到的 \ 用来转义 "
- 字符串必须使用转义双引号括起来,这样才会生成实际意义上的字符串。
- 可以在代码中直接使用
BuildConfig.API_URL
- 还可以通过类似的方式来配置资源值:带不带括号都可以
debug{
resValue("string","app_name","Example DEBUG")
}
release{
resValue "string","app_name","Example"
}
3. 项目范围的设置
如果在一项目中,有多个 Android 模块,多个模块中具有重复性的设置,那么可以将重复性的设置定义在顶层构建文件中。
Gradle 允许在 Project 对象上添加额外属性,这意味着任何 build.gradle
文件都能定义额外的属性,添加额外属性需要通过 ext
代码块。
ext{
compileSdkVersion = 28
buildToolsVersion = "28.0.1"
}

这段代码使得模块层的构建文件( app
下的 build.gradle
)可以使用 rootProject
来获取属性:

4. 项目属性
ext
代码块是定义额外属性的一种方式。我们可以使用属性来动态定制构建过程。
定义属性的方式有多种,这里介绍三种常用的:
-
ext 代码块
-
gradle.properties 文件
-
-P 命令行参数
-
示例:
-
image
-
image
-
-
在命令行中输入:
gradlew printProperties -Pcmd='from the command line'
-
image
-
-
这里实际上是新建了一个任务
Task
,并且在命令行中执行了它 -
image
我们可以同时在顶层构建文件和模块构建文件中定义属性,如果一个模块定义了一个在顶层文件中早已存在的属性时,那么新属性将会直接覆盖原来的属性。
5. 默认的任务
如果没有指定任何任务而运行 Gradle 的话,那么会默认运行 help
任务,它会打印一些任何使用 Gradle 的信息。 help
任务被设置为默认的任务,在每次运行没有明确指定任务的 Gradle 时,可以覆盖默认的任务,添加一个或多个常用的任务。
在顶层 build.gradle 文件中加入一行,来指定默认的任务:
defaultTasks("clean","assembleDebug")
可以在命令行中使用 gradlew tasks | grep "Default tasks"
查看默认任务

四、总结
构建是什么,构建任务是什么,如何通过命令行执行构建任务,如何配置构建过程。
下一章:依赖管理。
网友评论