Gradle笔记_2-基本自定义构建
《Gradle for Android 中文版》笔记
理解Gradle文件
Android Studio创建项目,会默认生成三个 Gradle 文件。
MyApp
- build.gradle
- settings.gradle
- app
- build.gradle
settings 文件
settings.gradle 文件内容如下示例:
include ':app', ':commonlite'
rootProject.name='MyApp'
settings 文件在初始化阶段被执行,定义了哪些模块应该包含在构建内。
多模块项目必须有 settings 文件。
顶层构建文件
即项目的 build.gradle 文件,默认情况下包含如下两个代码块:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
}
}
allprojects {
repositories {
jcenter()
}
}
buildscript 代码块中的 repositories 代码块,将其中的 JCenter 配置成一个仓库,一个仓库代表一系列依赖包(或者说一系列可下载的函数库)。
dependencies 代码块用于配置构建过程中的依赖包。不能将你的应用或依赖项目所需要的依赖包放在顶层构建文件中。
allprojects 代码块用来声明那些需要被用于所有模块的属性。
模块构建文件
Andorid app 模块构建文件,可以覆盖顶层 build.gradle 文件的任何属性,示例如下:
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.package.myapp"
minSdkVersion 19
targetSdkVersion 29
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.aar', '*.jar'], exclude: [])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation project(path: ':commonlite')
}
- 插件
第一行用到了 Android 应用插件,该插件在顶层构建文件中被配置成了依赖。提供构建、测试和打包 Android 应用以及依赖项目的所有任务。
- Android
android 代码块,包含了全部的 Android 特有配置。
必须有的属性:
- compileSdkVersion ,编译应用的 Android API 版本。
- buildToolsVersion ,构建工具和编译器使用的版本号。
构建工具包包含命令行应用,如aapt、zipalign、dx 和 renderscript,这些都被用来在打包应用时生成各种中间产物。
defaultConfig 代码块用于配置应用的核心属性。
applicationId 应用的唯一标识,覆盖了 manifest 文件中的 package,两者有所不同:
- applicationId作用是应用的唯一标识。
- manifest 文件中的 package作为包名用在源代码和 R 类中。
minSdkVersion:配置运行应用的最小 API 级别
targetSdkVersion:用于通知系统已经在某特定 Android 版本通过测试,不必启用任何向前兼容的行为。
versionCode:版本号
versionName:版本名称
manifest 中的配置作为后备。
- dependencies
定义了一个应用或依赖项目所有的依赖包。
任务入门
Terminal 中运行 gradlew tasks
命令,会打印出所有可用任务。在新建的项目中,会包括:
- Android tasks
- Build tasks
- Build setup tasks
- Cleanup tasks
- Help tasks
- Install tasks
- Verification tasks
- Other tasks
如果还想看到它们之间的依赖,可以运行gradlew tasks --all
。该命令会试运行这些任务,可通过添加-m
或--dry-run
来做一次试运行。
基础任务
Gradle 的 Android 插件使用了 Java 基础插件,Java 基础插件又使用了基础插件。
基础插件添加了任务的标准生命周期和一些共同约定的属性。
基础插件定义了 assemble 和 clean 任务,Java 插件定义了 check 和 build tasks。
基础插件定义的任务的约定:
- assemble:集合项目的输出。
- clean:清理项目的输出。
- check:运行所有检查,通常是单元测试和集成测试。
- build:同时运行 assemble 和 check。
在这些基本任务上 Android 插件也添加了很多 Android 特有的任务。
Android 任务
Android 插件扩展了基本任务,并实现了它们的行为。Android 环境下基本任务所做的事情:
- assemble:为每个构建版本创建一个 apk。
- clean:清除所有的构建内容,例如 apk 文件。
- check:运行 Lint 检查,如果 Lint 发现一个问题,则可终止构建。
- build:同时运行 assemble 和 check。
assemble 任务 默认依赖于 assembleDebug 和 assembleRelease,如果添加了更多的构建类型,就会有更多的任务。
Android 插件还添加了一些新任务,值得注意的新任务:
- connectedCheck:在连接设备或模拟器上运行测试。
- deviceCheck:一个占位任务,专为其他插件在远程端设备上运行测试。
- installDebug 和 installRelease:在连接设备或模拟其上安装特定版本。
- 所有的 install tasks 都会有相关的 uninstall 任务。
构建任务依赖于 check,而不是 connectedCheck 和 deviceCheck。因为构建任务只需要保证正常的 check,而无需一个连接的设备或模拟器。
运行 check 任务会生成一份 Lint 报告,里面包含所有的警告和错误,以及一份详细的说明和一个相关文档的链接。
该报告在 app/build/outputs 目录下,名称为 lint-result.html。
当你集合一份生产版本时,Lint 将会检查那些导致应用崩溃的致命问题。一旦发现有问题,Lint 就会终止构建,并在命令行界面打印错误信息。Lint 也会在 app/build/reports 文件夹下生成一份叫做 lint-results-release-fatal.html 的报告,可以右键->open in browser 在浏览器中查看,比在命令行界面滚动查看更方便,他会指引你到问题的详细描述。
Android Studio
在 Gradle 任务窗口中(通常在右侧工具栏),可以通过简单的双击任务的名称来运行某个任务。
自定义构建
当你在 Android Studio 中编写构建文件时,无论你在构建文件中定义了什么,都应该同步该项目,当添加依赖或添加 BuildConfig 变量时同步尤为重要。可根据提示或者点击同步按钮执行同步操作。
在底层,同步实际上运行了 generateDebugSources 任务来生成所有必须的类。
操控 manifest 条目
我们可以直接通过构建文件而不是 manifest 文件来配置:
- applicationId
- minSdkVersion
- targetSdkVersion
- versionCode
- versionName
以及:
- testApplicationId:针对 instrument 测试 apk 的 applicationId。
- testInstrumentationRunner:JUnit测试运行器的名称,被用来运行测试。
- singningConfig:签名配置。
- proguardFile 和 proguardFiles:混淆文件配置。
在Android Studio内部 可以通过 Project Structure 对话框修改基本的设置。
BuildConfig 和资源
自 SDK 工具版本升级到17之后,构建工具都会生成一个叫做 BuildConfig 的类,
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "your applicationId";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "";
public static final int VERSION_CODE = 8;
public static final String VERSION_NAME = "4.0.4";
}
其中有一个 DEBUG 常量,如果有一部分代码只想在 debugging 时期(debug 版本)运行,比如 logging,就可以用这个常量作判断。
android {
buildTypes {
debug {
buildConfigField "String", "API_URL", "\"http://example.com/test/api\""
buildConfigField "boolean", "LOG_HTTP_CALLS", "true"
}
release {
buildConfigField "String", "API_URL", "\"http://example.com/api\""
buildConfigField "boolean", "LOG_HTTP_CALLS", "false"
}
}
}
在构建文件中创建 BuildConfig 字段,字符串必须用转义双引号括起来。
在添加 buildConfigField 后,就可以在项目代码中使用 BuildConfig.API_URL 和 BuildConfig.LOG_HTTP_CALLS 。
类似的方式,配置资源值:
android {
buildTypes {
debug {
resValue "string", "app_name", "Example Debug"
}
release {
resValue "string", "app_name", "Example"
}
}
}
这里可以不加转义双引号。通过 resources 获取:
String appName = getResources().getString(R.string.a)
项目范围的设置
如果一个项目中有多个 Android 模块,我们知道,顶层构建文件中,allprojects 中定义的的依赖仓库会应用到所有的模块,同样的,也可以使用相同的策略来运用 Android 特定的设置:
allprojects {
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
}
}
该段代码只有在你所有模块都是 Android app 项目时才有效(因为 apply plugin: 'com.android.application'
),因为你需要 Android 插件获取 Android 特有的属性。
Gradle 允许在 Project 对象上添加额外属性。意味着任何 .gradle 文件都能定义额外属性,添加额外属性需要通过 ext 代码块。
可以在顶层构建文件添加一个含有自定义属性的 ext 代码块;
ext {
compileSdkVersion = 29
buildToolsVersion = "29.0.2"
}
在模块(module)构建文件可以使用 rootProject 来获取属性:
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
}
项目属性
三种默认定义属性的方法:
- ext 代码块
- gradle.properties 文件
- -P 命令行参数
下面代码包含了三种添加额外属性的方法,
在 build.gradle 文件中添加代码:
ext {
local = "Hello from build.gradle"
}
task printProperties {
println local // Local extra property
println propertiesFile // Property from gradle.properties
if (project.hasProperty("cmd")) {
println cmd // Command line property
}
}
在 gradle.properties 文件中添加属性:
propertiesFile = Hello from gradle.properties
在 Terminal 输入运行 printProperties 任务的命令,通过 -P 命令行附上 cmd 属性:
gradlew printProperties -Pcmd="Hello from the command line"
输出如下:
Hello from build.gradle
Hello from gradle.properties
Hello from the command line
模块构建文件中定义的属性在顶层文件已经存在,将会覆盖顶层文件中的属性。
默认的任务
如果没有指定任何任务而运行 Gradle 的话,会运行 help 任务,会打印一些如何使用 Gradle 工作的信息。
help 任务被设置为默认任务。可以覆写默认任务,添加一个甚至多个任务。
在顶层 build.gradle 文件中加入一行,用来指定默认任务:
defaultTasks 'clean', 'assembleDebug'
当运行没有任何参数的 Gradle wrapper 时(Terminal 中输入命令 gradlew
),它会运行 clean 和 assembleDebug 任务。
通过运行 tasks 任务和格式化输出,可以清晰地看到哪些任务被设置为默认任务。