Kotlin 35. Android Gradle 介绍

一起来学Kotlin:概念:22. Android Gradle 介绍

当我们刚开始进行安卓开发的时候,没有人关注 Gradle。我们主要专注于编写 Kotlin 代码和尽可能美观的 Android 应用程序。但随着时间的变化,我自己对 Gradle 感到越来越好奇。到底什么是 Gradle?我究竟应该怎么用?

在构建这些应用的时候,有时我们会偶然发现一个已经被互联网上其他人解决的问题,他们很友好地以库的形式分享他们的项目,我们可以在我们的应用程序中实现,并根据我们的需要定制它。为此,我们使用 build.gradle 文件来实现那些帮助我们构建应用程序的库,方法是指定它们的唯一包名称和版本。 这可能是我们在 Android 项目中使用 Gradle 最常见的用例。

但除此之外呢?我自己在写代码的时候,gradle的各个文件都是敬而远之的,不敢修改,也不愿修改,这就让我对 gradle 越来越好奇了。如果你和我一样,也想进一步对 gradle 有所了解,那么可以将这篇博客看完。



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 布局中打开我们的项目结构时,这可能容易把我们搞混,但它们的名称旁边会包含 ProjectModule 形式的小描述。

请添加图片描述

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 文件中提到的大部分基本内容。

猜你喜欢

转载自blog.csdn.net/zyctimes/article/details/129151354