可能大家开发安卓已经很久了,但对Android gradle的使用完全了解了吗,本篇基于官方文档整理,希望能帮助你系统的了解Android gradle的原理及使用;
配置构建
Android构建系统会编译应用资源和源代码,然后将它们打包到 APK 中,供您测试、部署、签名和分发。Android Studio 会使用高级构建工具包 Gradle 来自动执行和管理构建流程,同时也允许您定义灵活的自定义构建配置。每个构建配置均可自行定义一组代码和资源,同时重复利用所有应用版本共用的部分。Android Plugin for Gradle 与该构建工具包搭配使用,提供专用于构建和测试 Android 应用的流程和可配置设置。
Gradle 和 Android 插件独立于 Android Studio 运行。这意味着,您可以在 Android Studio 内、计算机上的命令行或未安装 Android Studio 的计算机(如持续集成服务器)上构建 Android 应用。如果您不使用 Android Studio,可以学习如何通过命令行构建和运行应用。无论您是从命令行、在远程计算机上还是使用 Android Studio 构建项目,构建的输出都相同。
注意:由于 Gradle 和 Android 插件独立于 Android Studio 运行,因此您需要单独更新构建工具。请阅读版本说明,了解如何更新 Gradle 和 Android 插件。
Android 构建系统非常灵活,让您能够在不修改应用核心源文件的情况下执行自定义构建配置。本部分将介绍 Android 构建系统的工作原理,以及它如何帮助您对多个构建配置进行自定义和自动化处理。如果您只想详细了解如何部署应用,请参阅在 Android Studio 中构建和运行应用。如需立即开始使用 Android Studio 来创建自定义构建配置,请参阅配置构建变体。
构建流程
构建流程涉及许多将项目转换成 Android 应用软件包 (APK) 的工具和流程。构建流程非常灵活,因此了解它的一些底层工作原理会很有帮助。
如图 1 所示,典型 Android 应用模块的构建流程通常按照以下步骤执行:
编译器将您的源代码转换成 DEX 文件(Dalvik 可执行文件,其中包括在 Android 设备上运行的字节码),并将其他所有内容转换成编译后的资源。
APK 打包器将 DEX 文件和编译后的资源合并到一个 APK 中。不过,在将应用安装并部署到 Android 设备之前,必须先为 APK 签名。
-
APK 打包器使用调试或发布密钥库为 APK 签名:
- 如果您构建的是调试版应用(即专用于测试和分析的应用),则打包器会使用调试密钥库为应用签名。Android Studio 会自动使用调试密钥库配置新项目。
- 如果您构建的是打算对外发布的发布版应用,则打包器会使用发布密钥库为应用签名。如需创建发布密钥库,请参阅在 Android Studio 中为应用签名。
在生成最终 APK 之前,打包器会使用 zipalign 工具对应用进行优化,以减少其在设备上运行时所占用的内存。
构建流程结束时,您将获得应用的调试版 APK 或发布版 APK,以用于部署、测试或发布给外部用户。
自定义构建配置
Gradle 和 Android 插件可帮助您完成以下方面的构建配置:
构建类型
构建类型定义 Gradle在构建和打包应用时使用的某些属性,通常针对开发生命周期的不同阶段进行配置。例如,调试构建类型支持调试选项,并使用调试密钥为 APK 签名;而发布构建类型则会缩减 APK、对 APK 进行混淆处理,并使用发布密钥为 APK 签名以进行分发。如需构建应用,您必须至少定义一个构建类型。Android Studio 默认会创建调试和发布两个构建类型。如需开始为应用自定义打包设置,请了解如何配置构建类型。产品变种
产品变种代表您可以向用户发布的应用的不同版本,如应用的免费版和付费版。您可以自定义产品变种来使用不同的代码和资源,同时共享和重复利用所有应用版本共用的部分。产品变种是可选的,您必须手动创建。如今日头条的正常版本和极速版等。构建变体
构建变体是构建类型与产品变种的交叉产物,也是 Gradle 用来构建应用的配置。利用构建变体,您可以在开发期间构建产品变种的调试版本,或者构建产品变种的已签名发布版本以供分发。虽然您无法直接配置构建变体,但可以配置组成它们的构建类型和产品变种。创建额外的构建类型或产品变种也会创建额外的构建变体。清单条目
您可以在构建变体配置中为清单文件的某些属性指定值。这些构建值会替换清单文件中的现有值。如果您要为模块生成多个 APK,让每一个 APK 文件都具有不同的应用名称、最低 SDK 版本或目标 SDK 版本,便可运用这一技巧。当存在多个清单时,Gradle 会合并清单设置。依赖项
您可以在构建变体配置中为清单文件的某些属性指定值。这些构建值会替换清单文件中的现有值。如果您要为模块生成多个 APK,让每一个 APK 文件都具有不同的应用名称、最低 SDK 版本或目标 SDK 版本,便可运用这一技巧。当存在多个清单时,Gradle 会合并清单设置。签名
您可以在构建变体配置中为清单文件的某些属性指定值。这些构建值会替换清单文件中的现有值。如果您要为模块生成多个 APK,让每一个 APK 文件都具有不同的应用名称、最低 SDK 版本或目标 SDK 版本,便可运用这一技巧。当存在多个清单时,Gradle 会合并清单设置。代码和资源压缩
构建系统让您能够为每个构建变体指定不同的 ProGuard 规则文件。在构建应用时,构建系统会应用一组适当的规则来使用其内置的缩减工具(如 R8)缩减您的代码和资源。多 APK 支持
构建系统让您能够自动构建不同的 APK,并且每个 APK 只包含特定屏幕密度或应用二进制接口 (ABI) 所需的代码和资源。
构建配置文件
Gradle 设置文件
settings.gradle 文件位于项目的根目录下,用于指示 Gradle 在构建应用时应将哪些模块包含在内。对大多数项目而言,该文件很简单,只包含以下内容:
include ‘:app’
不过,多模块项目需要指定应包含在最终构建中的每个模块。
顶层构建文件
顶层 build.gradle 文件位于项目的根目录下,用于定义适用于项目中所有模块的构建配置。默认情况下,顶层构建文件使用 buildscript 代码块来定义项目中所有模块共用的 Gradle 代码库和依赖项。以下代码示例说明了创建新项目后可在顶层 build.gradle 文件中找到的默认设置和 DSL 元素。
/**
* 在buildscript块中,您可以配置存储库和Gradle本身的依赖关系,意味着,您不应包含依赖关系用于此处的模块。例如,此块包含
* 用于Gradle作为依赖项,因为它提供了Gradle的附加说明需要构建Android应用模块。
*/
buildscript {
/**
* 存储库块配置Gradle用来存储的存储库搜索或下载依赖项。Gradle预配置对远程的支持存储库,
* 例如JCenter,Maven Central和Ivy。您也可以使用本地存储库或定义自己的远程存储库。
* 下面的代码定义将JCenter、google()和自定义的作为Gradle的存储库来查找其依赖项。
*/
repositories {
google()
jcenter()
maven { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter' }
}
/**
* 依赖关系块配置Gradle需要使用的依赖关系建立您的项目。以下行为Gradle添加了Android插件版本4.0.0作为类路径依赖项。
*/
dependencies {
classpath 'com.android.tools.build:gradle:4.0.0'
/**
* 注意:不要将您的应用程序依赖项放在这里;它们属于在单独的模块build.gradle文件中
*/
}
}
/**
* allprojects块是您配置存储库和项目中所有模块使用的依赖项,例如第三方插件或库。但是,您应该在每个模块级的build.gradle文件。
* 对于新项目,Android Studio默认情况下包括JCenter和Google的Maven存储库。
*/
allprojects {
repositories {
google()
jcenter()
maven {
url "http://mvn.gt.igexin.com/nexus/content/repositories/releases/"
}
maven { url "https://jitpack.io" }
}
}
配置项目全局属性
对于包含多个模块的 Android 项目,可能有必要在项目层级定义某些属性并在所有模块之间共享这些属性。为此,您可以将额外的属性添加到顶层 build.gradle 文件内的 ext 代码块中。
buildscript {...}
allprojects {...}
// 此块封装了自定义属性,并使它们对所有module可用项目中的模块。
ext {
// 以下仅是您可以定义的属性类型的几个示例。
compileSdkVersion = 28
// 您还可以创建属性以指定依赖项的版本。模块之间具有一致的版本可以避免与行为发生冲突。
supportLibVersion = "28.0.0"
...
}
...
要从同一项目中的模块访问这些属性,请在该模块的 build.gradle 文件(您可以在下一部分中详细了解此文件)中使用以下语法。
android {
// 使用以下语法访问您在项目级别定义的属性:rootProject.ext.property_name
compileSdkVersion rootProject.ext.compileSdkVersion
...
}
...
dependencies {
implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
...
}
注意:虽然 Gradle 可让您在模块级别定义项目全局属性,但您应避免这样做,因为这样会导致共享这些属性的模块进行耦合。模块耦合使得以后将模块作为独立项目导出更加困难,并实际妨碍 Gradle 利用并行项目执行来加快多模块构建。
模块级构建文件
模块级 build.gradle 文件位于每个 project/module/ 目录下,用于为其所在的特定模块配置构建设置。您可以通过配置这些构建设置来提供自定义打包选项(如额外的构建类型和产品变种),以及替换 main/ 应用清单或顶层 build.gradle 文件中的设置。
以下 Android 应用模块 build.gradle 文件示例简要说明了您应该了解的一些基础 DSL 元素和设置。
/**
* 构建配置的第一行将Android插件应用于 扩展到此版本,并使android块可用于指定 特定于Android的构建选项。
*/
apply plugin: 'com.android.library'
/**
* android块是您配置所有特定于Android的地方构建选项。
*/
android {
/**
* compileSdkVersion指定Gradle应该使用的Android API级别编译您的应用程序。这意味着您的应用可以使用其中包含的API功能和此API级别及更低。
*/
compileSdkVersion 29
/**
* buildToolsVersion指定SDK生成工具的版本,命令行Gradle用于构建应用程序的实用程序和编译器。你需要使用SDK Manager下载构建工具。
* 此属性是可选的,因为插件默认情况下使用推荐的版本为构建工具。
*/
buildToolsVersion "29.0.2"
/**
* defaultConfig块封装了所有的默认设置和条目构建变体,并且可以覆盖main / AndroidManifest.xml中的某些属性
* 。您可以配置产品变体以覆盖这些值适用于您应用的不同版本。
*/
defaultConfig {
/**
* applicationId唯一标识要发布的包。 但是,您的源代码仍应引用程序包名称由main / AndroidManifest.xml文件中的package属性定义。
*/
applicationId 'com.example.myandroidxdemo'
/**
* 定义运行应用程序所需的最低API级别。
*/
minSdkVersion 21
/**
* 指定用于测试应用程序的API级别。
*/
targetSdkVersion 29
/**
* 定义您的应用程序的版本号。
*/
versionCode 1
/**
* 为您的应用定义用户友好的版本名称。
*/
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles 'consumer-rules.pro'
}
/**
* 您可以在buildTypes块中配置多种构建类型。默认情况下,构建系统定义两种构建类型:调试和发布。默认版本配置中未明确显示
* 调试版本类型,但其中包含调试工具,并使用调试密钥进行了签名。发布构建类型适用Proguard设置,并且默认情况下未签名。
*/
buildTypes {
/**
* 默认情况下,Android Studio将发布版本类型配置为启用代码使用minifyEnabled缩小,并指定默认的Proguard规则文件。
*/
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
/**
* 您可以在productFlavors块中配置多种产品变种。这使您可以创建应用的不同版本,用自己的设置覆盖defaultConfig块。
* 产品维度是可选的,系统默认不会创建它们。需要我们手动创建
* 此示例创建了免费和付费的产品样式。每种产品的变体指定其自己的应用程序ID,以便它们可以在Google上存在同时存放
* Play商店或Android设备。如果声明产品变体,则还必须声明变体维度,并将每种变体分配给变体维度。
*/
/**
* 指定该项目的产品变种维度的名称
* 使用Android插件3.0.0及更高版本配置产品变种时,您必须使用flavorDimensions属性至少指定一个变种维度,
* 然后将每个变种分配给一个维度。否则,您将收到以下构建错误:
* Error:All flavors must now belong to a named flavor dimension.
* The flavor 'flavor_name' is not assigned to a flavor dimension.
*/
flavorDimensions 'api', 'version'
/**
* 默认情况下,当您仅指定一个维度时,您配置的所有样式都会自动属于该维度。如果指定多个维度,则需要手动将每种产品变种分配给
* 一个维度,如下面的示例所示。
* flavorDimensions允许您创建可以与其他flavorDimensions的flavor组合的productFlavors组。
* 例如,您可以具有一个维度,其中包括应用程序的“免费”和“付费”版本,而另一个维度用于支持不同API级别的变体
* (例如“ minApi21”和“ minApi24”)。然后,Android插件可以结合这些方面的特点(包括其设置,代码和资源)来创建变体,
* 例如“ debugFreeMinApi21”和“releasePaidMinApi24”等。下面的示例向您展示如何指定flavorDimension以及如何向
* 其中添加productFlavor。
*/
productFlavors {
demo {
// 将此产品变种分配给“version”组
dimension 'version'
}
full {
dimension 'version'
}
minApi24 {
// 将此产品变种分配给“api”组
dimension 'api'
minSdkVersion '24'
versionNameSuffix "-minApi24"
}
minApi21 {
dimension "api"
minSdkVersion '21'
versionNameSuffix "-minApi21"
}
}
/**
* 您可以在splits块中配置不同的APK版本, *每个仅包含代码和资源以实现受支持的屏幕密度,或者ABI。您还需要配置构建,
* 以便每个APK都有一个不同的versionCode。
*/
splits {
// 用于根据屏幕密度构建多个APK的设置。
density {
// 启用或禁用构建多个APK。
enable false
// 构建多个APK时,请排除这些密度。
exclude "ldpi", "tvdpi", "xxxhdpi", "400dpi", "560dpi"
}
}
}
/**
* 模块级构建配置文件中的依赖项块指定仅构建模块本身所需的依赖项。 要了解更多信息,请转到添加构建依赖项。
*/
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
}
Gradle 属性文件
Gradle 还包含两个属性文件,它们位于项目的根目录下,可用于指定 Gradle 构建工具包本身的设置:
gradle.properties
:您可以在其中配置项目全局 Gradle 设置,如 Gradle 守护进程的最大堆大小。
local.properties
:为构建系统配置本地环境属性,其中包括:
- ndk.dir - NDK 的路径。此属性已被弃用。NDK 的所有下载版本都将安装在 Android SDK 目录下的 ndk 目录中。
- sdk.dir - SDK 的路径。
- cmake.dir - CMake 的路径。
- ndk.symlinkdir - 在 Android Studio 3.5 及更高版本中,创建指向 NDK 的符号链接,该链接可比 NDK 安装路径短。
将 NDK 重新映射到较短的路径(仅限 Windows)
Windows 长路径最常见的问题就是 NDK 安装文件夹中的工具(如 ld.exe)会产生非常深的路径,但工具对于长路径的支持并不佳。
在 local.properties 中,您可以设置 ndk.symlinkdir 属性来请求 Gradle 插件创建指向 NDK 的符号链接。该符号链接的路径可比现有 NDK 文件夹的路径短。例如,ndk.symlinkdir = C:\ 将生成以下符号链接:C:\ndk\19.0.5232133
将项目与 Gradle 文件同步
当您在项目中对构建配置文件进行更改时,Android Studio 会要求您同步项目文件,以便它导入构建配置更改并执行一些检查来确保您的配置不会造成构建错误。
要同步项目文件,请点击做出更改后显示的通知栏中的 Sync Now(如图 3 所示),或者点击菜单栏中的 Sync Project 图标
。如果 Android Studio 发现您的配置有任何错误(例如,您的源代码使用了只有在 compileSdkVersion 以上的 API 级别中才会提供的 API 功能),就会显示 Messages 窗口来说明该问题。
源代码集
Android Studio 按逻辑关系将每个模块的源代码和资源分组为源代码集。模块的 main/ 源代码集包含其所有构建变体共用的代码和资源。其他源代码集目录是可选的,在您配置新的构建变体时,Android Studio 不会自动为您创建这些目录。不过,创建类似于 main/ 的源代码集有助于更好地组织管理 Gradle 仅在构建特定应用版本时才应使用的文件和资源:
src/main/
:此源代码集包含所有构建变体共用的代码和资源。
src/buildType/
:创建此源代码集可加入特定构建类型专用的代码和资源。
src/productFlavor/
:创建此源代码集可加入特定产品变种专用的代码和资源。
注意:如果配置构建以组合多个产品变种,则可以为变种维度之间的每个产品变种组合创建源代码集目录:src/productFlavor1ProductFlavor2/
src/productFlavorBuildType/
:创建此源代码集可加入特定构建变体专用的代码和资源。
例如,如需生成应用的“fullDebug”版本,构建系统需要合并来自以下源代码集的代码、设置和资源:
-
src/fullDebug/
:(构建变体源代码集) -
src/debug/
:(构建类型源代码集) -
src/full/
:(产品变种源代码集) -
src/main/
:(主源代码集)
注意:当您在 Android Studio 中使用 File > New 菜单选项新建文件或目录时,可以针对特定源代码集进行创建。可供您选择的源代码集取决于您的构建配置,如果所需的目录尚不存在,Android Studio 会自动创建。
如果不同源代码集包含同一文件的不同版本,Gradle 将按以下优先顺序决定使用哪一个文件(左侧源代码集替换右侧源代码集的文件和设置):
构建变体 > 构建类型 > 产品变种 > 主源代码集 > 库依赖项
这样一来,Gradle 便可使用专用于您试图构建的构建变体的文件,同时重复利用与应用的其他版本共用的 Activity、应用逻辑和资源。在合并多个清单时,Gradle 会使用相同的优先顺序,这样每个构建变体都能在最终清单中定义不同的组件或权限。