一起来学Kotlin:概念:22. Android Gradle 介绍
当我们刚开始进行安卓开发的时候,没有人关注 Gradle。我们主要专注于编写 Kotlin 代码和尽可能美观的 Android 应用程序。但随着时间的变化,我自己对 Gradle 感到越来越好奇。到底什么是 Gradle?我究竟应该怎么用?
在构建这些应用的时候,有时我们会偶然发现一个已经被互联网上其他人解决的问题,他们很友好地以库的形式分享他们的项目,我们可以在我们的应用程序中实现,并根据我们的需要定制它。为此,我们使用 build.gradle
文件来实现那些帮助我们构建应用程序的库,方法是指定它们的唯一包名称和版本。 这可能是我们在 Android 项目中使用 Gradle 最常见的用例。
但除此之外呢?我自己在写代码的时候,gradle的各个文件都是敬而远之的,不敢修改,也不愿修改,这就让我对 gradle 越来越好奇了。如果你和我一样,也想进一步对 gradle 有所了解,那么可以将这篇博客看完。
文章目录
- 一起来学Kotlin:概念:22. Android Gradle 介绍
- 1 什么是 Gradle
- 2 build.gradle 以及 settings.gradle
- 2.1 settings.gradle
- 2.2 build.gradle (Project)
- 2.3 build.gradle (Module)
1 什么是 Gradle
Gradle 是我们用于 Android 开发的构建(build)工具,用于自动化构建和发布应用程序的过程。 我们可能认为构建和运行应用程序非常简单,直接在 Android Studio 中按下运行按钮就可以了。 好吧,实际上,这个按钮背后会触发 Gradle 的内置任务(函数),这些任务负责在我们的模拟器或真实设备上运行应用程序。 这个过程需要几个步骤才能成功完成,以便我们看到正在运行的应用程序。以下是当我们按下运行按钮时发生的一般步骤:
- Gradle 读取应用程序的构建配置文件 (build.gradle),其中包含有关依赖项、构建类型等的信息。
- Gradle 下载并解析应用程序的依赖项。
- Gradle 编译应用程序的代码,包括将 Java 或 Kotlin 代码转换为字节码。
- 之后,Gradle 将编译后的代码和资源打包到一个 APK 文件中。
Gradle 带有许多内置功能,但它也允许我们编写自己的逻辑。 它提供自己的领域特定语言 (domain-specific language / DSL),这是一种为构建自动化领域量身定制的编程语言,它基于 Groovy 或 Kotlin 来描述构建脚本。
无论我们使用哪种编程语言,gradle 文件的结构都是相同的,它们都是从 DSL 的相同部分构建的。
2 build.gradle 以及 settings.gradle
Android 项目包含一个 settings.gradle
文件和两个 build.gradle
文件,其中一个放在根目录中,另一个包含在 app 模块中。 当我们在 Android 布局中打开我们的项目结构时,这可能容易把我们搞混,但它们的名称旁边会包含 Project
和 Module
形式的小描述。
2.1 settings.gradle
我们看到,除了这两个之外,根目录中还有一个 settings.gradle
文件。让我们从它开始理解 gradle 文件的过程。
上图左侧显示了用 Groovy 编写的 settings.gradle 文件,在右侧显示了用 Kotlin 编写的相同文件。它里面有两个主要部分:
- 插件管理
- 依赖解析管理
这两个部分都是常规函数,但是因为它们只接收一个参数并且该参数是 lambda 函数的形式,所以我们可以忽略括号。
pluginManagement
函数包含一个 lambda 函数作为参数,它提供了一个 PluginManagementSpec
参数,可以通过 Groovy
中的“it”或 Kotlin 语言关键字中的“this”访问(但我们不需要明确指定它们)。 在 PluginManagementSpec
中,我们可以找到一个名为 repositories
的新函数,它包含新的 lambda 函数作为参数,并在内部提供了一个 RepositoryHandler
参数。 那是我们传递存储库(repositories)列表的地方。 这里提到的存储库,基本上代表 Gradle 将尝试查找插件(我们项目所需的插件)并下载它找到的插件的地方。 稍后,我们将看到我们需要指定必要插件的地方在哪里。
dependencyResolutionManagement
功能与 pluginManagement
功能类似,但它提供了存储库列表,Gradle 将在其中搜索项目所需的依赖项。
那么,插件(plugins)和依赖项(dependencies)有什么区别?依赖项是我们在开发应用程序时可以在 Kotlin 代码中使用的所有第三方库。另一方面,插件类似于依赖项; 最大的区别在于插件提供了 Gradle 在构建我们的项目时使用的所有任务(功能)。所以它基本上是我们 gradle 文件的第三方库。
Groovy vs Kotlin gradle functions
在 settings.gradle
文件的底部有一行指定项目中包含哪些模块,在 Groovy 中,该行代码看起来类似 include ':app'
。这句话实际上指的是一个常规函数 include,接收一个类型为 String 的变量。Groovy
具有一项功能,使开发人员能够调用需要一个参数且不带括号的函数。 在 Groovy
中,我们可以使用单引号和双引号定义字符串。所以 Kotlin 中的等价行是 include(”:app”)
。
2.2 build.gradle (Project)
项目级 build.gradle
文件用于定义整个项目的全局配置和设置。 它还用于在顶层实现依赖项和插件。 默认情况下,build.gradle (Project)
中的所有配置和设置都应由项目中的所有模块继承,并且 build.gradle (Module)
文件能够覆盖它们。
在项目级 build.gradle
中设置的最常见的东西是构建 Android 应用程序所需的插件,例如:
- Android Gradle
- Kotlin
- Hilt
有时我们还需要添加我们希望跨模块使用的库,例如:
- Android Support Library
- Google Play Services Library
这是我们在启动新的 Android 项目时拥有的项目级 build.gradle 的示例。
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '7.2.1' apply false
id 'com.android.library' version '7.2.1' apply false
id 'org.jetbrains.kotlin.android' version '1.6.10' apply false
}
task clean(type: Delete) {
delete rootProject.buildDir
}
对我们来说重要的部分是 plugins 方法,它使我们能够定义我们的 Android 项目必不可少的核心插件。下面,我们来看一下定义这些插件的语法:首先,我们调用 id
函数并将一个参数作为 String 类型传递,该参数表示我们要使用的插件的唯一包名称。 这相当于 id(”com.android.application”)
。下一步是设置上述插件的版本; 这也是一个接受一个字符串类型参数的函数。 这里的技巧是版本函数只能从 PluginDependencySpec
对象调用,并且我们收到的对象是 id("...")
函数的结果。 这同样适用于 apply
关键字; 它也是一个函数,就像 version
一样,但它接受一个布尔值作为参数。 如果我们想将其迁移到 Kotlin 以提高此代码的可读性,则该行将类似于 id(“com.android.application”).version(“7.2.1”).apply(false)
。
2.3 build.gradle (Module)
最后一个也是最常用的一个是我们应用程序模块中的 build.gradle。 它用于定义用于此特定模块的配置和设置。 在功能方面,它具有与项目级 build.gradle 类似的选项,但它带来了关注点分离。 因此,我们想要在我们的应用程序模块中放置的 Kotlin 代码中使用的所有库和框架,都应该在这个 gradle 文件的依赖项块中定义。 这些库工作所需的所有插件也应该在同一个 gradle 文件中定义。
如果我们查看 build.gradle (Module)
,我们可以找到三个主要部分:
- Plugins
- Android
- Dependencies
我们已经熟悉了插件和依赖项部分(它们与我们已经介绍过的非常相似)。这里的新事物是 android 部分。这是我们可以对我们的应用程序进行大量配置更改的地方。 开发人员在这里设置的最常见的东西是:
- minSdk、targetSdk、compileSdk的版本。
- 应用程序的版本代码和名称。
- 产品口味和构建类型。
以下是 build.gradle (Module)
的示例。
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
android {
compileSdk 32
defaultConfig {
applicationId "com.example.myapplication"
minSdk 28
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.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 文件中提到的大部分基本内容。