AndroidStudio构建系统使用Gradle工具来管理和执行构建流程。
典型 Android 应用模块的构建流程按照以下常规步骤执行:
构建流程结束时,将获得应用的调试版或发布版 APK/AAB,以用于部署、测试或向外部用户发布。
APP和AAB
开始新项目时,AndroidStudio 会自动创建其中的部分文件,文件目录如下
App/
|--build.gradle
|--settings.gradle
|--app/
|--build.gradle
|--build/
|--libs/
|--src/
|--main/
|--java/
|--com.example.app/
|--res/
|--drawable/
|--layout/
|--...
|--AndroidManifest.xml
|--aidl/
Gradle的配置文件分为两个部分
一部分在项目根目录下包括settings.gradle
和build.gradle
,settings.gradle
用于定义项目级代码库设置,并告知 Gradle 在构建应用时应将哪些模块包含在内。build.gradle
用于定义适用于项目中所有模块的依赖项。
settings.gradle
pluginManagement {//插件管理
repositories {//搜索或下载Gradle插件的仓库依赖
gradlePluginPortal()
google()//Google's Maven repository
mavenCentral()//Maven Central Repository
}
}
dependencyResolutionManagement {//依赖项解析管理
/**
* 存储库模式:
* PREFER_PROJECT --首选项目远程仓库
* PREFER_SETTINGS--首选settings远程仓库
* FAIL_ON_PROJECT_REPOS--强制settings远程仓库
*/
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)//设置存储库的方法
repositories {
google()//Google's Maven repository
mavenCentral()//Maven Central Repository
}
}
rootProject.name = "My Application"//根工程的名字
include ':app'//包含的子模块
pluginManagement | 插件管理 |
repositories | 仓库依赖 |
Google’s Maven repository | |
mavenCentral | Maven Central Repository |
dependencyResolutionManagement | 依赖项解析管理 |
repositoriesMode.set | 设置存储库的方法 |
rootProject.name | 根工程的名字 |
include | 包含的子模块 |
存储库模式:
build.gradle
plugins {//插件
//根build配置中应该声明 apply false ,而在子工程中不应该声明 apply false
id 'com.android.application' version '7.2.2' apply false //app
id 'com.android.library' version '7.2.2' apply false //library
id 'org.jetbrains.kotlin.android' version '1.7.0' apply false //kotlin
}
task clean(type: Delete) { //任务
delete rootProject.buildDir //删除build目录
}
plugins | 插件 |
‘com.android.application’ | app |
‘com.android.library’ | library |
‘org.jetbrains.kotlin.android’ | kotlin |
task | 任务 |
delete | 删除 |
rootProject.buildDir | build目录 |
配置全局属性
可以在build.gradle
中配置额外的全局属性,供其他子模块使用
ext { //全局配置
sdkVersion = 28
supportLibVersion = "28.0.0"
}
使用的时候
android {
// rootProject.ext.property_name
compileSdkVersion rootProject.ext.compileSdkVersion
...
}
模块build配置是位于每个工程模块目录下的build.gradle
文件,用于为其所在的特定模块配置 build 设置。
可以通过配置这些 build 设置提供自定义打包选项(如额外的 build 类型和产品变种),以及覆盖 main/
应用清单或顶层 build.gradle
文件中的设置。
plugins { //必须在第一行,配置gradle插件
id 'com.android.application' //app
}
android { //配置android构建选项
compileSdk 32 //编译应用程序时应使用的Android API级别
defaultConfig { //声明默认配置。封装所有构建变体的默认设置和条目,并可以覆盖main/AndroidManifest中的某些属性
applicationId "com.android" //包名
minSdk 26 //最小支持的API级别
targetSdk 32 //用于测试应用程序的API级别
versionCode 1 //版本号
versionName "1.0" //版本名
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" //测试环境
}
//默认情况下,Android Studio使用minifyEnabled配置发布版本类型以启用代码收缩,并指定默认的Proguard混淆规则文件。
buildTypes { //build 类型
release { //发布版本
minifyEnabled false //是否启动混淆 ture:打开 false:关闭
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
//混淆规则文件
}
}
compileOptions { //编译选项
sourceCompatibility JavaVersion.VERSION_1_8 //编译.java文件的jdk版本
targetCompatibility JavaVersion.VERSION_1_8 //确保生成的类文件与targetCompatible指定的VM兼容
}
//如果声明产品变种,还必须声明产品的维度,并将每个变种分配给一个维度。
flavorDimensions "product" //声明产品的维度
//创建应用程序的不同版本,这些版本可以使用自己的设置覆盖defaultConfig块。
//产品变种是可选的,默认情况下构建系统不会创建它们。
productFlavors {//配置多种产品变种
A { //产品变种
dimension "product" //产品维度
applicationId 'com.android.a' //重新声明的包名
}
B { //产品变种
dimension "product"
applicationId 'com.android.b'
}
}
}
dependencies {//依赖
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
plugins
声明工程的类型,必须在第一行。
plugins | 配置gradle插件 |
android
配置android构建选项
compileSdk | 编译应用程序时应使用的Android API级别 |
defaultConfig | 声明默认配置。 |
applicationId | 包名 |
minSdk | 最小支持的API级别 |
targetSdk | 用于测试应用程序的API级别 |
versionCode | 版本号 |
versionName | 版本名 |
testInstrumentationRunner | 测试环境 |
buildTypes | build 类型 |
minifyEnabled | 是否启动混淆 |
proguardFiles | 混淆文件 |
compileOptions | 编译选项 |
sourceCompatibility | 编译.java文件的jdk版本 |
targetCompatibility | 确保生成的类文件与targetCompatible指定的VM兼容 |
flavorDimensions | 声明产品的维度 |
productFlavors | 配置多种产品变种 |
dimension | 产品维度 |
dependencies
依赖
dependencies {//依赖
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
Gradle 还包含两个属性文件,它们位于项目的根目录下,可用于指定 Gradle 构建工具包本身的设置:
gradle.properties
可以在其中配置项目全局 Gradle 设置,如 Gradle 守护程序的最大堆大小。
//指定用于守护进程的JVM参数
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
//使用AndroidX软件包结构
android.useAndroidX=true
//启用每个库的R类的名称空间,以便其R类仅包含库本身中声明的资源,而不包含库依赖项中的资源,从而减少该库的R类别的大小
android.nonTransitiveRClass=true
local.properties
为构建系统配置本地环境属性,其中包括:
ndk.dir
- NDK 的路径。此属性已被弃用。NDK 的所有下载版本都将安装在 Android SDK 目录下的 ndk
目录中。sdk.dir
- SDK 的路径。cmake.dir
- CMake 的路径。ndk.symlinkdir
- 在 Android Studio 3.5 及更高版本中,创建指向 NDK 的符号链接,该符号链接的路径可比 NDK 安装路径短。Android Studio 按逻辑关系将每个模块的源代码和资源分组为源代码集。模块的 main/
源代码集包含其所有 build 变体共用的代码和资源。其他源代码集目录是可选的,在配置新的 build 变体时,Android Studio 不会自动为您创建这些目录。
src/main/
此源代码集包含所有 build 变体共用的代码和资源。
src/buildType/
创建此源代码集可加入特定 build 类型专用的代码和资源。
src/productFlavor/
创建此源代码集可加入特定产品变种专用的代码和资源。
注意:如果配置 build 以组合多个产品变种,则可以为变种维度之间的每个产品变种组合创建源代码集目录:
src/productFlavor1ProductFlavor2/
src/productFlavorBuildType/
创建此源代码集可加入特定 build 变体专用的代码和资源。
例如,如需生成应用的fullDebug
版本,构建系统需要合并来自以下源代码集的代码、设置和资源:
src/fullDebug/
(build 变体源代码集)src/debug/
(build 类型源代码集)src/full/
(产品变种源代码集)src/main/
(主源代码集)文件使用顺序
如果不同源代码集包含同一文件的不同版本,Gradle 将按以下优先顺序决定使用哪一个文件
build 变体 > build 类型 > 产品变种 > 主源代码集 > 库依赖项
使用 sourceSets
代码块更改 Gradle 为源代码集的每个组件收集文件的位置。sourceSets
代码块必须位于 android
代码块中。
sourceSets {//代码源文件配置。可以列出多个目录,Gradle将使用所有目录来收集
main {//封装main代码集的配置
//更改Java源的目录。默认是 'src/main/java'.
java.srcDirs = ['other/java']
//资源文件源的目录。默认目录是“src/main/res”。
//由于Gradle赋予这些目录同等的优先级,如果在多个目录中定义相同的资源,则在合并资源时会出现错误。
res.srcDirs = ['other/res1', 'other/res2']
//aidl文件源的目录。默认目录是“src/main/aidl”。
aidl.srcDirs = ['src/main/aidl', 'other/aidl']
//对于每个源集,您只能指定一个Android清单。
//默认情况下,Android Studio为main源创建AndroidManifest,设置在src/main/目录中。
manifest.srcFile 'other/AndroidManifest.xml'
//注意:应该避免指定一个目录,该目录是指定的一个或多个其他目录的父目录。
}
//创建其他块配置的源代码集。
androidTest {
//如果源代码集的所有文件都位于单个根目录下,则可以使用setRoot属性指定该目录。
//为源代码集收集源时,Gradle只查找相对于指定的根目录的位置。
//例如,在将下面的配置应用于androidTest源集之后,Gradle仅在src/tests/Java/目录中查找Java源。
setRoot 'src/tests'
}
}
sourceSets | 代码源文件配置。 |
main | main代码集的配置 |
java.srcDirs | Java源的目录。默认目录是 ‘src/main/java’. |
res.srcDirs | 资源文件源的目录。默认目录是“src/main/res” |
aidl.srcDirs | aidl文件源的目录。默认目录是“src/main/aidl”。 |
manifest.srcFile | 配置文件,默认在src/main/目录中 |
一个源目录只能属于一个源代码集。例如,不能同时与 test
和 androidTest
源代码集共享同一测试源代码。
一个源目录也只能有一个AndroidManifest.xml
配置
在 dependencies
代码块内,可以从多种不同的依赖项配置中选择其一 来声明库依赖项。
implementation
Gradle 会将依赖项添加到编译类路径,并将依赖项打包到构建输出。不过,当模块配置 implementation
依赖项时,其他模块只有在运行时才能使用该依赖项。
使用此依赖项配置代替 api
或 compile
(已弃用)可以显著缩短构建时间,因为这样可以减少构建系统需要重新编译的模块数。例如,如果 implementation
依赖项更改了其 API,Gradle 只会重新编译该依赖项以及直接依赖于它的模块。大多数应用和测试模块都应使用此配置。
api
Gradle 会将依赖项添加到编译类路径和构建输出。当一个模块包含 api
依赖项时,会让 Gradle 了解该模块要以传递方式将该依赖项导出到其他模块,以便这些模块在运行时和编译时都可以使用该依赖项。
此配置的行为类似于 compile
(现已弃用),但使用它时应格外小心,只能对需要以传递方式导出到其他上游消费者的依赖项使用它。这是因为,如果 api
依赖项更改了其外部 API,Gradle 会在编译时重新编译所有有权访问该依赖项的模块。因此,拥有大量的 api
依赖项会显著增加构建时间。除非要将依赖项的 API 公开给单独的模块,否则库模块应改用 implementation
依赖项。
compileOnly
Gradle 只会将依赖项添加到编译类路径(也就是说,不会将其添加到构建输出)。如果您创建 Android 模块时在编译期间需要相应依赖项,但它在运行时可有可无,此配置会很有用。
如果使用此配置,那么库模块必须包含一个运行时条件,用于检查是否提供了相应依赖项,然后适当地改变该模块的行为,以使该模块在未提供相应依赖项的情况下仍可正常运行。这样做不会添加不重要的瞬时依赖项,因而有助于减小最终 APK 的大小。此配置的行为类似于 provided
(现已弃用)。
注意:不能将
compileOnly
配置与 AAR 依赖项配合使用。
runtimeOnly
Gradle 只会将依赖项添加到构建输出,以便在运行时使用。也就是说,不会将其添加到编译类路径。此配置的行为类似于 apk
(现已弃用)。
annotationProcessor
如需添加对作为注解处理器的库的依赖,必须使用 annotationProcessor
配置将其添加到注解处理器的类路径。这是因为,使用此配置可以将编译类路径与注释处理器类路径分开,从而提高构建性能。如果 Gradle 在编译类路径上找到注释处理器,则会禁用避免编译功能,这样会对构建时间产生负面影响(Gradle 5.0 及更高版本会忽略在编译类路径上找到的注释处理器)。
如果 JAR 文件包含以下文件,则 Android Gradle 插件会假定依赖项是注释处理器:
META-INF/services/javax.annotation.processing.Processor
。 如果插件检测到编译类路径上包含注解处理器,则会产生构建错误。
lintChecks
使用此配置可以添加您希望 Gradle 在构建项目时执行的 lint 检查。
注意:使用 Android Gradle 插件 3.4.0 及更高版本时,此依赖项配置不再将 lint 检查打包在 Android 库项目中。如需将 lint 检查依赖项包含在 AAR 库中,请使用下面介绍的
lintPublish
配置。
lintPublish
在 Android 库项目中使用此配置可以添加希望 Gradle 编译成 lint.jar
文件并打包在 AAR 中的 lint 检查。这会使得使用 AAR 的项目也应用这些 lint 检查。如果之前使用 lintChecks
依赖项配置将 lint 检查添加到已发布的 AAR 中,则需要迁移这些依赖项以改用 lintPublish
配置。
弃用的配置
apk | Gradle 只会将依赖项添加到构建输出,以便在运行时使用。也就是说,不会将其添加到编译类路径。 |
compile | Gradle 会将依赖项添加到编译类路径和构建输出。 将依赖项导出到其他模块。 |
provided | Gradle 只会将依赖项添加到编译类路径(也就是说,不会将其添加到构建输出)。 |
除非明确定义发布 build 的签名配置,否则 Gradle 不会为该 build 的 APK 或 AAB 文件签名。
//buildTypes {
// release {
// signingConfig signingConfigs.release
// }
//}
signingConfigs {
release {
storeFile file("releasekey.keystore")
storePassword "password"
keyAlias "ReleaseKey"
keyPassword "password"
}
}
如需从环境变量获取这些密码,请添加以下代码:
storePassword System.getenv("KSTOREPWD")
keyPassword System.getenv("KEYPWD")
build 类型
build 类型定义 Gradle 在构建和打包应用时使用的某些属性,通常针对开发生命周期的不同阶段进行配置。例如,调试 build 类型会启用调试选项,并会使用调试密钥为应用签名;而发布 build 类型则可能会缩减应用大小、对应用进行混淆处理,并使用发布密钥为应用签名以进行分发。
产品变种 (Product flavor)
产品变种代表您可以向用户发布的不同应用版本,如免费版应用和付费版应用。可以自定义产品变种以使用不同的代码和资源,同时共享并重用所有应用版本共用的部分。产品变种是可选的,必须手动创建。
build 变体
build 变体是 build 类型与产品变种的交叉产物,也是 Gradle 用来构建应用的配置。利用 build 变体,可以在开发期间构建产品变种的调试版本,或者构建产品变种的已签名发布版本以供分发。虽然无法直接配置 build 变体,但可以配置组成它们的 build 类型和产品变种。创建额外的 build 类型或产品变种也会产生额外的 build 变体。
清单 (Manifest) 条目
可以在 build 变体配置中为清单文件的某些属性指定值。这些 build 值会覆盖清单文件中的现有值。如果要为应用生成多个变体,让每一个变体都具有不同的应用名称、最低 SDK 版本或目标 SDK 版本,便可运用这一技巧。当存在多个清单时,Gradle 会合并清单设置。
依赖项
构建系统会管理来自本地文件系统以及来自远程代码库的项目依赖项。这样一来,您就不必手动搜索、下载依赖项的二进制文件包以及将它们复制到项目目录中。
签名
构建系统既允许在 build 配置中指定签名设置,也可以在构建流程中自动为应用签名。构建系统通过已知凭据使用默认密钥和证书为调试版本签名,以避免在构建时提示输入密码。除非为此 build 明确定义签名配置,否则,构建系统不会为发布版本签名。
代码和资源缩减
构建系统允许为每个 build 变体指定不同的 ProGuard 规则文件。在构建应用时,构建系统会应用一组适当的规则以使用其内置的缩减工具(如 R8)缩减代码和资源 。
多 APK 支持
通过构建系统可以自动构建不同的 APK,并让每个 APK 只包含特定屏幕密度或应用二进制接口 (ABI) 所需的代码和资源。