Android Gradle 是 Android 项目的构建工具,它基于 Gradle 构建系统,为 Android 应用的构建、测试、发布提供支持。Gradle 配置文件通常分为两个层级:项目级别的 build.gradle 文件 和 模块级别的 build.gradle 文件。
• 项目级 build.gradle:包含项目的全局配置。
• 模块级 build.gradle:针对特定模块(如 app 模块)进行配置。
接下来分别介绍这两个文件的作用、常用配置项,以及如何动态获取配置。
1. 项目级 build.gradle 文件
1.1 文件位置
项目级 build.gradle 文件位于项目根目录下,通常用于配置全局的插件和依赖、构建脚本仓库等。
1.2 常见配置
// 项目级别的 build.gradle 文件示例
buildscript {
repositories {
google() // 使用 Google's Maven 仓库
mavenCentral() // 使用 Maven Central 仓库
}
dependencies {
// Gradle 插件的依赖
classpath 'com.android.tools.build:gradle:7.2.0' // Android Gradle 插件版本
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10' // Kotlin 插件版本
}
}
allprojects {
repositories {
// 各模块共享的仓库配置
google()
mavenCentral()
}
dependencies {
implementation 'com.android.support:appcompat-v7:28.0.0'
}
}
subprojects {
repositories {
mavenCentral()
}
}
plugins {
id 'com.android.application' version '8.2.1' apply false
id 'com.android.library' version '8.2.1' apply false
id 'org.jetbrains.kotlin.android' version '1.8.0' apply false
}
task clean(type: Delete) {
delete rootProject.buildDir // 自定义清理任务,删除构建目录
}
1.3 配置项说明
1.3.1 buildscript:
用于配置构建脚本本身的特定部分。它的作用是定义 构建脚本的依赖项 和 构建脚本所需的仓库,以及如何应用这些插件或依赖项。
buildscript 的作用:
- 定义构建脚本的依赖项(Classpath) :
buildscript 主要用来定义构建脚本本身所依赖的类路径(classpath)。这意味着构建过程中所需要的插件或者工具的依赖是通过 buildscript 中的 dependencies 来声明的。例如,Android 项目通常会在这里声明 Android Gradle 插件(com.android.tools.build:gradle)和 Kotlin 插件(org.jetbrains.kotlin:kotlin-gradle-plugin)等。
- 定义仓库(Repositories) :
repositories 作用是指定从哪里下载这些构建插件和依赖。通常会配置一些常用的仓库,如 google() 和 mavenCentral()。这些仓库包含了常见的插件和库。
- 为整个项目或子项目提供构建插件:
buildscript 中配置的插件和依赖项通常会被用于构建项目,而不是在应用程序代码中使用。例如,Android Gradle 插件就在 buildscript 中声明,并且会影响整个项目的构建过程。
结构说明:
-
repositories 定义了构建过程中所需依赖的下载源。常用的仓库有:
- google():适用于 Android Gradle 插件等 Android 相关依赖。
- mavenCentral():适用于各种 Java 和 Kotlin 依赖。
必要性:
- 插件管理:buildscript 使你能够指定构建过程所需要的插件和其版本,保证了构建环境中插件版本的统一性
- 支持多模块构建:对于大型项目,可能会有多个模块(如应用模块、库模块等),buildscript 中的插件和依赖项会为所有这些模块提供共享的构建配置。
- 构建环境的配置:通过 buildscript 配置,可以确保整个项目的构建过程使用的插件、工具和版本都是一致的,这有助于避免由于插件版本不一致导致的构建失败或异常。
1.3.2 allprojects:
用于配置 所有子项目(包括根项目和所有子模块)的构建设置。这些配置会应用到项目的所有子模块,允许在多个项目或模块之间共享。通常用于统一管理多个子项目的构建仓库、依赖项、插件等。
allprojects 的作用:
-
共享仓库配置:
allprojects 块通常用于为项目的所有子模块配置共享的仓库。这样,所有子模块都可以从相同的仓库中下载依赖项。你不需要在每个子模块的 build.gradle 文件中单独配置仓库。
-
共享插件和依赖配置:
如果有多个子项目,并且希望它们使用相同的插件或依赖项,可以通过 allprojects 来统一配置。这使得管理依赖和插件变得更加高效。
-
统一配置设置:
除了仓库和依赖,allprojects 还可以用于设置其他共享的构建设置,例如版本号、代码风格、任务等。这种方式非常适用于大型多模块的项目,可以避免在每个子项目中重复配置。
- repositories:定义了所有子项目(子模块)共享的仓库,确保每个模块都能访问到需要的依赖。
结构说明:
- repositories:用于配置所有子项目共享的仓库。无需在多个子模块的 build.gradle 文件中重复声明仓库。比如配置了 google() 和 mavenCentral(),所有子项目都会使用这些仓库来查找和下载依赖。
- dependencies:配置共享的依赖项。这些依赖项会被自动应用到所有子项目
必要性:
- 统一的仓库配置:多模块项目统一配置所有模块使用相同的仓库,避免在每个模块中重复配置仓库。
- 共享的依赖配置:为所有子项目统一配置共享的依赖,用于共享一些公共的库或插件
- 统一的构建设置:用来统一所有模块的构建设置。例如,你可以配置所有模块的 Java 版本、Kotlin 编译选项等。
allprojects {
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
tasks.withType(KotlinCompile) {
kotlinOptions.jvmTarget = "1.8"
}
}
1.3.3 subprojects
subprojects基本和allprojects一致,但是subprojects 只会影响子项目,而不会影响根项目:
- allprojects:适用于根项目及其所有子项目。配置项会影响根项目和所有子项目。
- subprojects:只会影响子项目(不包括根项目)。如果你有多个子模块,并且希望对子模块的构建配置进行统一管理,但不影响根项目,可以使用 subprojects。
如果你有多个子模块,并且希望对子模块的构建配置进行统一管理,但不影响根项目,可以使用 subprojects。
1.3.4 plugins
plugins 块用于声明和应用 Gradle 插件。这些插件扩展了 Gradle 构建系统的功能,允许使用特定的功能或任务,例如 Android 构建、Kotlin 编译、Java 编译等。使得管理插件的方式更加清晰简洁。
plugins的作用:
-
声明插件:
声明构建过程中要使用的插件,插件通过 ID 和版本号来标识。与 buildscript 中使用 classpath 声明插件不同,plugins 更简单。
-
应用插件:
插件是 Gradle 构建系统的核心扩展部分。通过 plugins 块,Gradle 会自动下载并应用所声明的插件,使得你可以使用该插件提供的任务、功能和配置。例如,Android 插件可以用来构建 Android 应用,Kotlin 插件可以用来编译 Kotlin 代码。
-
自动处理插件版本管理:
使用 plugins 块时,插件的版本号可以直接指定,Gradle 会自动从插件仓库下载对应的插件,而不需要手动设置插件依赖。这使得版本管理更加简洁,避免了手动管理插件版本的复杂性。
-
提高可读性和可维护性:
plugins 块声明插件的语法更直观和简洁,代码更加简洁、易懂,并且使得构建脚本的结构更清晰。
项目级的 Gradle 插件,一般用于全局配置。如插件定义、依赖管理等。可以跨多个子模块共享,减少了重复配置的需要。通过使用插件,Gradle 可以获得额外的功能。也能集中管理构建工具的版本,避免每个子项目都独立管理插件版本。
关键字段
-
id:
插件的唯一标识符。每个插件都必须有一个唯一的 id,通常这个 id 由插件的开发者指定。例如,com.android.application 用于 Android 应用构建插件,org.jetbrains.kotlin.android 用于 Kotlin 插件。
-
version:
插件的版本号。你可以指定插件的版本号,这样 Gradle 会确保使用指定版本的插件。例如,version '8.2.1' 表示使用该版本的插件。
-
apply:
指定插件是否被应用到项目中。
apply false
用于在项目级 build.gradle 文件中声明插件,而实际应用插件的操作可能在子项目中进行,避免根项目直接应用插件。例如,apply false
表示插件不会自动应用到项目中,而是可以在子模块中按需使用。可以在模块级的 build.gradle 中选择性地启用插件。
必要性:
- 语法更简洁:plugins 块的语法比传统的 buildscript 更简洁、直观。在 buildscript 中,你需要手动指定插件的类路径(classpath),而 plugins 块通过插件的 ID 和版本号来声明插件,Gradle 会自动管理依赖。
- 更易于维护:不需要手动添加 classpath 依赖并管理插件版本,Gradle 会自动处理。
- 减少冲突:通过指定插件的版本号,可以确保不同的模块或子项目使用一致的插件版本,避免了版本冲突的问题。
- 减少重复配置:支持在多个模块中应用同样的插件,通过声明并共享插件配置,减少了重复代码。
plugins 与 buildscript 的区别:
- plugins :是一个简洁的插件声明方式,通常用于声明和应用插件。它会自动从插件仓库下载插件并进行版本管理。
- buildscript :通常用于声明插件的类路径(classpath),适用于需要自定义插件或插件类路径的情况。
1.3.5 task clean
-
自定义 Gradle 任务,删除构建目录,通常用于清理构建结果。在该示例中,其作用如下:
- task clean:这是一个自定义任务,用于删除构建目录 build。通常在执行 ./gradlew clean 命令时,Gradle 会调用这个任务来清理生成的构建文件。
- type: Delete:指定该任务的类型是 Delete,表示删除文件或目录。
- delete rootProject.buildDir:表示删除根项目的构建目录,即 rootProject/build。
1.4 动态获取配置的方式
ext {
// 定义一个全局的版本号
kotlin_version = '1.6.10'
}
// 在子项目中引用
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
通过 ext 属性可以定义全局变量,然后在各模块中引用这些变量。
2. 模块级 build.gradle 文件
2.1 文件位置
每个 Android 模块(如 app)都有自己的 build.gradle 文件,用于配置该模块的构建选项和依赖。
2.2 常见配置
// 模块级别的 build.gradle 文件示例
plugins {
id 'com.android.application' // Android 应用插件
id 'org.jetbrains.kotlin.android' // Kotlin 插件
}
android {
compileSdkVersion 34 // 编译 SDK 版本
defaultConfig {
applicationId "com.example.myapp" // 应用 ID
minSdkVersion 21 // 最小支持 SDK 版本
targetSdkVersion 34 // 目标 SDK 版本
versionCode 1 // 版本号
versionName "1.0" // 版本名称
}
buildTypes {
release {
minifyEnabled true // 启用代码混淆
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' // 配置 ProGuard
}
debug {
minifyEnabled false // 调试版本禁用混淆
}
}
productFlavors {
free {
applicationIdSuffix ".free" // 应用 ID 后缀
}
paid {
applicationIdSuffix ".paid" // 应用 ID 后缀
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17 // 设置 Java 编译版本
targetCompatibility JavaVersion.VERSION_17
}
buildFeatures {
viewBinding true // 启用 ViewBinding
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.4.1' // AppCompat 库
implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.6.10' // Kotlin 库
testImplementation 'junit:junit:4.13.2' // JUnit 测试库
}
2.3 配置项说明
2.3.1 plugins
声明并应用 Gradle 插件。通过插件启用构建特性或任务。例如,com.android.application 用于构建 Android 应用,org.jetbrains.kotlin.android 用于在 Android 项目中使用 Kotlin。
plugins 既可以在项目级的 build.gradle 文件中配置,也可以在模块级的 build.gradle 文件中配置。虽然它们的配置方式有所不同,但主要的区别在于作用范围和功能。
其和根目录下项目级的plugins的区别如下:
1. 项目级 plugins
-
作用范围:在项目级的 build.gradle 中配置的插件,通常用于定义整个项目的构建逻辑,或者应用于所有模块(子项目)中。
-
作用:项目级插件配置主要用来为所有子模块提供构建工具、插件或库的版本管理。这些插件通常是全局插件,确保整个项目或所有模块使用相同的构建配置、版本等。
-
常见用法:配置用于构建 Android 项目所需的插件、Kotlin 插件等。
-
项目级插件的一些常见功能:
- 插件版本管理:你可以在项目级别声明插件的版本,避免在每个模块中重复配置插件版本。
- 全局插件配置:例如,Android 和 Kotlin 插件通常需要在项目级别声明。
2. 模块级 plugins
-
作用范围:在模块级的 build.gradle 中配置的插件,作用仅限于该模块。每个模块的 build.gradle 文件通常会指定与该模块相关的插件。
-
作用:模块级插件用于具体化某个模块的构建逻辑。例如,如果某个模块是 Android 应用模块,则可以在该模块的 build.gradle 文件中启用 com.android.application 插件。如果是库模块,则启用 com.android.library 插件。
-
常见用法:在各个模块中配置 Android 插件、Kotlin 插件,或其他库插件等。
-
模块级插件的一些常见功能:
- Android 构建插件:根据模块的性质,使用 com.android.application 或 com.android.library 插件来构建 Android 应用或库。
- Kotlin 插件:启用 Kotlin 支持并为模块提供编译和其他 Kotlin 特性。
3. 区别总结
项 目 | 项目级 plugins 配置 | 模块级 plugins 配置 |
---|---|---|
作用范围 | 整个项目(包括所有子模块) | 仅限于当前模块(子模块) |
配置方式 | 通常在项目根目录的 build.gradle 文件中配置 | 每个模块的 build.gradle 文件中配置 |
插件类型 | 一般为全局性插件,例如 Android、Kotlin 等 | 与模块构建相关的插件,例如 com.android.application ,com.android.library 等 |
常见用途 | 管理插件版本、全局配置插件 | 针对每个模块的具体构建任务,如构建 Android 应用或库 |
4. 插件的应用
- 项目级插件配置:主要目的是统一插件版本,确保所有模块使用相同的版本。例如,Android Gradle 插件和 Kotlin 插件的版本需要在项目级别一致。
- 模块级插件配置:在模块级的 build.gradle 中,针对不同的模块选择相应的插件并应用。例如,一个模块可能是 Android 应用模块 (com.android.application),另一个模块可能是 Android 库模块 (com.android.library)。
2.3.2 android 配置
-
compileSdkVersion:指定应用编译时使用的 Android SDK 版本。
-
defaultConfig:模块的基本配置,包括应用 ID、最小 SDK 版本、目标 SDK 版本、版本号等。
常用字段:
- applicationId:应用的唯一标识符。
- minSdk:最低支持的 Android SDK 版本。
- targetSdk:应用优化支持的目标 SDK 版本。
- versionCode:版本号,唯一且递增,用于标识不同版本的应用。
- versionName:版本名称,通常是用户可见的版本号(如 1.0)。
-
buildTypes:配置不同的构建类型,如 debug 和 release。每个构建类型可以有不同的设置,如是否混淆代码、是否启用调试信息等。
常用字段
- isMinifyEnabled:是否启用代码压缩和混淆。true 表示启用混淆,false 表示不启用。
- proguardFiles:指定混淆配置文件,getDefaultProguardFile 获取默认的 ProGuard 配置,通常用于 release 构建类型。
-
productFlavors:定义产品类别,可以用来区分不同的产品版本(如 free 和 paid,或者 mobile 和 pad),用于创建不同版本的应用。
常用字段:
- applicationIdSuffix:应用 ID 后缀,不同的类型可以有不同的应用 ID
- versionNameSuffix:版本名称后缀,用于区分不同版本。
-
compileOptions:用于配置 Java 编译选项,确保项目兼容性和提升构建性能。
-
buildFeatures:用于启用或禁用 Android 构建系统中的某些特性的一部分。它允许开发者开启或关闭一些构建功能,比如 ViewBinding、DataBinding、Jetpack Compose 等。这些功能帮助简化开发过程,提升开发效率,并且提高项目的可维护性。
配置项
-
viewBinding:启用或禁用 ViewBinding,它是一种自动生成视图绑定类的功能,可以避免 findViewById 操作,简化代码,提升开发效率。默认情况下,viewBinding 是禁用的。
-
dataBinding:启用或禁用 DataBinding,允许将 UI 元素和数据对象绑定在一起,简化 UI 更新的代码。
-
compose: 启用或禁用 Jetpack Compose,这是 Android 的声明式 UI 框架,用于更简洁地构建用户界面。
-
buildConfig:启用或禁用 BuildConfig 文件的自动生成。它允许在构建时生成一些常用的构建常量(如版本号、构建类型等)。
-
customBuildFeatures:一些特定于插件的功能,允许你开启或关闭其他的构建功能。
示例:
-
android {
compileSdkVersion 34
defaultConfig {
applicationId "com.example.app"
minSdkVersion 21
targetSdkVersion 34
}
buildFeatures {
viewBinding = true // 启用 ViewBinding
dataBinding = false // 禁用 DataBinding
compose = true // 启用 Jetpack Compose
buildConfig = true // 启用 BuildConfig
}
}
-
dependencies:用于声明项目所依赖的外部库或模块。它指定了哪些依赖项需要在构建过程中被包括到 APK 或 AAB 中。通过声明这些依赖项,Gradle 会自动下载、编译并将其打包到项目中 常用配置:
- implementation:它表示库或模块是项目的实现依赖(即运行时和编译时都需要),引入的库不会传递给其他模块,意味着它们不会作为依赖暴露给依赖此项目的其他模块。
- api:通常用于库模块。当库模块依赖其他库时,这些库会暴露给依赖该库的其他模块,它们会成为公共的依赖。
- compileOnly:表示只在编译时需要,但不会包含在最终的 APK 中,适用于那些只在编译时需要存在的库(例如编译器插件或注解处理器)。
- runtimeOnly:表示只在运行时需要的库,不会在编译时提供。适用于运行时才需要的库,例如数据库驱动程序等。
- testImplementation:声明仅在测试代码中使用的依赖。它只影响测试构建过程,不会包含在主应用程序的构建中。适用于测试库、测试框架等。
- androidTestImplementation:声明仅在 Android 测试代码中使用的依赖。它只影响 Android 单元测试和 UI 测试。适用于 Android 测试框架。
- kapt:kapt 是 Kotlin 的注解处理工具(Kotlin Annotation Processing Tool)。它用来处理需要编译时注解的库或模块。适用于使用注解处理器的库。
- 动态获取依赖版本,通常使用版本范围来指定依赖项。例如:
dependencies { implementation 'com.squareup.okhttp3:okhttp:4.+' }
2.4 动态获取配置的方式
-
获取环境变量:
可以通过 Gradle 内置的 project 对象获取动态配置。例如,从外部文件或环境变量获取版本号。
def versionCode = project.hasProperty('versionCode') ? project.versionCode : 1
defaultConfig {
versionCode versionCode
}
-
动态加载属性文件:
使用 Properties 类动态加载版本号或其他配置。
def properties = new Properties()
file("local.properties").withInputStream { stream ->
properties.load(stream)
}
defaultConfig {
versionCode properties['versionCode'].toInteger()
versionName properties['versionName']
}
-
在 gradle.properties 文件中定义全局属性:
可以在 gradle.properties 文件中定义配置,并在 build.gradle 文件中引用。
# gradle.properties
VERSION_CODE=1
VERSION_NAME=1.0
然后在 build.gradle 中引用:
defaultConfig {
versionCode project.VERSION_CODE
versionName project.VERSION_NAME
}
总结
-
项目级 build.gradle:
- 用于配置全局构建环境,主要包括插件依赖、仓库配置、构建脚本的版本等。
- 动态获取配置信息可以通过 ext 定义全局变量,并在模块级别的 build.gradle 中引用。
-
模块级 build.gradle:
- 用于配置特定模块(如 app)的编译和构建选项,包含构建类型(buildTypes)、产品类型(productFlavors)、依赖关系等。
- 可以通过动态获取配置(如从 gradle.properties 或外部文件中加载)来实现灵活的构建。