给 Android 开发者的 Gradle 入门指南(Beginner’s Guide to Gradle for Android Developers)

By | 2018年7月12日

The goal of this article is to give you a high level overview of Gradle and how it fits into the entire build system when developing Android applications. I’ll go through the basics of Gradle and the Android Plugin for Gradle. I’ll then go through the default build.gradle scripts that come with a new Android Project.

This article will not teach you how to write custom Gradle scripts or anything of that sort. At the title says, it’s really meant for beginners.

本文的目的是为您提供关于 Gradle 的高级概述,以及在开发 Android 应用程序时如何适应整个构建系统。 我将通过 Gradle 和 Gradle 的 Android 插件的基础知识,以及新的 Android 项目附带的默认 build.gradle 脚本来进行讲述。

本文不会教你如何编写定制的 Gradle 脚本或任何类型的东西。正如标题所说,这是给真正意义上的初学者的文章。 

Backstory

I’ll start off with a confession: I’m mainly an iOS developer. Throughout my career, only a quarter of it has been spent working on Android applications. Because of this, I never really understood what Gradle was. I knew that it was “the thing” that went to work whenever I clicked on the green play button in Android Studio, but I had no idea what it actually did.

This lack of knowledge made me very impatient whenever I saw the words “Gradle Build Running” for more than 10 seconds. “What’s taking so long?” I’d ask Android Studio, hoping for some sort of a sign that it wasn’t just stuck. At work, whenever I saw an Android dev blankly staring at the screen, I’d often jokingly ask them “are you waiting for Gradle to build?”

Eventually I got frustrated and decided to figure out if I could cut down the build time. I watched a talk from Google I/O ’17 titled “Speeding Up Your Android Gradle Builds” confident that I’d unlock the key to all the Gradle speed I ever wanted.

What I got instead after 40 minutes was the realisation that I knew nothing about Gradle, hence I would have no chance at all at making it any better. I put my foot down and decided that it was time for me to understand Gradle.

背景故事

我先坦白一下:我主要是一名 iOS 开发人员。在整个职业生涯中,只有四分之一的时间用于开发 Android 应用程序。正因为如此,我从来没有真正理解 Gradle 是什么。当我点击 Android Studio 中的绿色播放按钮时,我知道这是“工作”,但我不知道它实际上做了什么。

当我看到“ Gradle Build Running ”这个词超过 10 秒时,这让缺少相关知识的我非常不耐烦。 “有什么需要这么久?”我会问 Android Studio ,希望有某种迹象表明它不仅仅是卡住了。在工作中,每当我看到一个 Android 开发者茫然地盯着屏幕,我经常开玩笑地问他们:“你是在等 Gradle 构建吗?

最终我感到沮丧,并决定找出要如何减少构建时间。我看了一个名为“加快 Android 的 Gradle 构建”的 Google I/O ’17  的演讲,相信会解开所有我想要的提升 Gradle 速度的关键。

40分钟之后,我意识到我对 Gradle 一无所知,所以我根本没有机会做得更好。 我停下脚步,决定现在是去理解 Gradle 的时候了。

The Basics

To kick things off, let’s clear up some things:

  1. Android Studio has no idea how to compile your Java & Kotlin code into an APK file.

  2. Gradle has no idea how to compile your Java & Kotlin code into an APK file either.

Yes, you read that correctly.

Gradle itself has no idea how to compile an APK file because Gradle is actually a general purpose build tool. It is not limited to building Android apps. On Gradle’s GitHub repository, it’s described as:

…a build tool with a focus on build automation and support for multi-language development. If you are building, testing, publishing, and deploying software on any platform, Gradle offers a flexible model that can support the entire development lifecycle from compiling and packaging code to publishing web sites.

On its own, Gradle itself isn’t actually able to do much. All of its useful features come from its rich plugin ecosystem. Think of all those third party libraries that you add into your Android app as plugins. You use those plugins to extend the functionality of your application, just like how Gradle uses plugins to extend its own functionality.

There are many plugins that come bundled with Gradle as well as many more that you can download. However if you go through the list of plugins that come with Gradle, you’ll realise that “Android” is nowhere to be found on that page.

基础知识

为了解决这个问题,让我们先弄清楚一些事情:

  1. Android Studio 不知道如何将 Java&Kotlin 代码编译成 APK 文件。

  2. Gradle 不知道如何将 Java&Kotlin 代码编译成 APK 文件。

是的,你没看错。

Gradle 本身并不知道如何编译 APK 文件,因为 Gradle 实际上是一个通用的构建工具。它不限于构建 Android 应用程序。在 Gradle 的 GitHub 仓库中,它被描述为:

…构建工具,着重于构建自动化和支持多语言开发。如果您在任何平台上构建、测试、发布和部署软件,Gradle 提供了一个灵活的模型,可以支持从编译和打包代码到发布的整个开发生命周期。 Gradle 本身实际上并不能做太多。所有有用的功能都来自丰富的插件生态系统。把你添加到 Android 应用程序中的所有第三方库视为插件。您可以使用这些插件来扩展应用程序的功能,就像 Gradle 使用插件来扩展自己的功能一样。

有很多与 Gradle 捆绑在一起的插件,以及更多可以下载的插件。但是,如果你阅读 Gradle 附带的插件列表,则会发现在该页面上找不到“Android”。

Android Plugin for Gradle

The Android Plugin for Gradle is the plugin that enables Gradle to be able to compile your code into an APK file, sign your APK with your keys and even install the APK onto your emulator or test devices. This plugin is what drives your entire build system.

Without it there’s just no way for Gradle to know how to do anything with your code. This is what I meant by both Android Studio and Gradle having no clue how to build your Android project: this plugin is the magic chain between Android Studio and Gradle.

Diving into the Scripts

Now that we’ve got some of the basics down, let’s look into how this actually translates to the real world. I’ll go through the files that you get when you start a brand new project in Android Studio:

(“Open up your Gradle file” they said..)

What are all these files for?

All the files with the word “gradle” in them are used to configure Gradle for our Android projects. There are multiple files because they all serve different purposes.

Android Plugin for Gradle

Android Plugin for Gradle 是一个使 Gradle 能够将您的代码编译成用你的密钥签名 APK 文件的插件,甚至将 APK 安装到你的模拟器或测试设备上。这个插件驱动你的整个构建系统。

没有它,Gradle 就无法知道如何对代码做任何事情。这也就是我前面说的 Android Studio 和 Gradle 不知道如何构建你的 Android 项目:这个插件是 Android Studio 和 Gradle 之间的魔法链。

深入脚本

现在我们已经掌握了一些基础知识,接下来看看如何转化为日常实现。当你在 Android Studio 中启动一个全新的项目时,会获得以下文件:

这些文件是什么?

所有带有“ gradle ”文字的文件都用于为我们的 Android 项目配置 Gradle 。里面存在多个文件,因为它们都有不同的用途。

Gradle Wrapper

The gradle-wrapper.properties file has one simple purpose: to determine which version of Gradle to use to build the project. It will then automatically download and store that version of Gradle for you. If you’re on a Mac, run the following command:ls ~/.gradle/wrapper/dists/ You’ll be able to see all the versions of Gradle that the Gradle Wrapper has ever downloaded for you.

(gradle-wrapper.properties)

Take note that your Gradle version is separate from your Android plugin version. At the time of writing, the current latest version of Gradle is v4.3. Android Studio still defaults to v4.1, so you can safely bump this up to v4.3 if you like.

settings.gradle

The settings.gradle file is where you inform Gradle about all of the sub-projects/modules that your project has. This is done through the includecommand. If you were to add another module into your project, Android Studio will automatically add it into this file.

build.gradle

From Gradle’s point of view, our project is considered a multi-project buildwhere you have a root project and one or more sub-projects. From an Android development point of view, these sub-projects are called modules.

Gradle Wrapper

gradle-wrapper.properties 文件有一个简单的目的:决定在构建项目时使用哪个 Gradle 版本。它将随后会自动为你下载并保存该版本的 Gradle 。如果你在 Mac 上使用,运行下面命令 ls ~/.gradle/wrapper/dists/ 你就可以看到 Gradle Wrapper 曾为你下载过的所有 Gradle 版本。

(gradle-wrapper.properties)

注意你的 Gradle 版本是独立于你的 Android 插件版本的。在本文撰稿时,目前最新的 Gradle 版本是 v4.3 。Android Studio 依然默认使用 v4.1 ,所以如果你愿意,你可以很安全的将版本升级到 v4.3 。

settings.gradle

settings.gradle 文件是保存在你通知 Gradle 的地方,即你的工程所有的子工程 /module 目录下。这是通过 include 命令完成的。如果你将另一个模块添加到你的工程中,Android Studio 将会自动将其添加到这个文件中。

build.gradle

从 Gradle 的角度来看,我们的工程被认为是一个多工程构建,其中你拥有一个根项目以及一个到多个子工程。从 Android 开发者的角度来看,这些子工程被称为 module(模块)。

This is why there are two build.gradle files that you see. One is for your root project, while the other is for the app module that comes with your project. Let’s start off with the one for your root project.

(Root project’s build.gradle)

  1. This entire buildscript{} block is used to tell Gradle script itself what it needs in order to compile this project.

  2. We declare Android Plugin for Gradle as one of the dependencies for this buildscript. “3.0.0” refers to the version of the plugin to be used.

  3. We tell Gradle to look for the things we need inside the google() Maven repository and jcenter() repository.

  4. Add an extra property to the Gradle project, allowing it to be accessible throughout the Gradle project. In other words, this is a Gradle style global variable. We can see this variable value being used to determine which version of the kotlin-gradle-plugin to be imported.

  5. As the name implies, the allprojects{} block is being used to inform Gradle that for all the sub-projects being compiled, use this set of repositories to resolve any required dependencies.

这就是为什么你会看到两个 build.gradle 文件的原因。一个是给根项目的,另一个是给伴随着你的项目的 app 模块的。让我们先看看你的根项目的格式吧。

(根项目的 build.gradle )

  1. 这个完整的 buildscript{} 块用于告知 Gradle 脚本本身,关于编译本项目需要的那些。

  2. 我们在这个 buildscript 中声明了 Android Gradle 插件的依赖性。“3.0.0” 表示要使用的插件版本。

  3. 我们告知 Gradle 我们需要到 google() Maven 代码库和 jcenter() 代码库中检索一些事项。

  4.  在Gradle 项目中添加额外的属性,以支持它可以在整个 Gradle 项目中是可访问的。换言之,这是 Gradle 风格的全局变量。我们可以通过使用决定所导入的 kotlin-gradle-plugin 的版本的方式来查看该变量的值。

  5. 正如名字所暗示的,allprojects{} 块被用于通知 Gradle 关于所有需要编译的子项目,并使用这个代码库集合来解决所有需要的依赖项。

(app module’s build.gradle)

  1. First we apply the actual Android plugin, then we apply the Kotlin Android plugin followed by its extensions plugin.

  2. The only reason this entire android{} block works is because we asked Gradle to apply the Android plugin mentioned previously. I’m sure you’re familiar with modifying values inside the block, but have you ever wondered what are all the possible values that you can put inside? Good thing it’s all documented here!

  3. This is where you will add all of your third party libraries as Gradle dependencies. Take note that there’s no repositories{} block inside your app’s build.gradle file. It’s not necessary since we already declared it using the allprojects{} block in the root project.

  4. Remember the global variable we declared in the root’s build file? Well here it is in action again. It’s probably a good idea to adopt the same technique for managing the version of your support libraries used to ensure that they all use the same version.

(app 模块的 build.gradle)

  1. 首先,我们应用真实的 Android 插件,然后我们使用其扩展插件来应用 Kotlin Android 插件。

  2. 此完整的 android{} 块工作的唯一原因是因为我们要求 Gradle 使用之前提到的 Android 插件。我深信你对修改该模块内部的值非常熟悉,但你是否对所有可能放入该块的值有过好奇呢?好事情是它在此都被文档化了!

  3. 这里就是你添加 Gradle 所依赖的第三方库的位置。注意在你的 app 的 build.gradle 中并没有 repositories{} 块。既然我们已经在根项目的 allprojects{} 块中声明了,这里就没有必要了。

  4. 还记得我们在根构建文件中的全局变量吗?是的,这里就是起作用的地方。最好采用类似管理你所支持库的版本一样的策略可能是个不错的主义,这可以保证他们都是用同一个版本。

Gradle Tasks

Now that we’ve dived through the scripts, there’s one more thing about Gradle that you need to know about: tasks.

Tasks are basically the things that Gradle can do whenever a build is triggered. Remember earlier I said that Android Studio has no idea how to compile your code? That’s because clicking on the big green play button in Android Studio will trigger a specific task for Gradle to perform.

On the bottom right corner, click on the “Gradle Console” button to open up the Gradle console. Then click on play button to run the app. A bunch of commands will appear, but we only care about the one at the top:

Executing tasks: [:app:assembleDebug]

We just told Gradle to perform the assembleDebug task. We can do the exact same thing via the command line. Click on the Terminal tab at the bottom left and run this command: ./gradlew assembleDebug --console plain

瞧!你只是让 Gradle 运行与播放按钮完全相同的命令。有几件事要注意:

  1. ./gradlew 意味着使用 Gradle Wrapper 来代替 “vanilla” Gradle 。强烈建议您始终使用 Wrapper 版本。

  2. assembleDebug 是你刚刚要求它运行的任务的名称。

  3. –console plain 告诉 Gradle 打印生成日志,就像你在 Android Studio 中看到的一样。完全是可选的。

让我们运行最后一个命令:./gradlew tasks

这个命令将列出 Gradle 目前在这个项目中所知道的所有任务,并提供每个任务的简短描述。很酷吧?

现在,点击 Android Studio 右上角的 Gradle 标签。

哈哈!这是一样的东西。这一部分只是列出了 Gradle 可以为这个项目运行的所有可能的任务。在这里双击 assembleDebug ,就可以做到与刚刚在命令行上做的一样的事情,并且和播放按钮做同样的事情。

如果您在 Android Studio 中运行“重建项目”命令,同时保持 Gradle 终端处于打开状态,你将会意识到它所做的只是运行 clean 任务,然后运行 assembleDebug 命令。这就是我发现在重建项目之前运行清理项目是完全不必要的,因为重建项目无论如何都会运行相同的 clean 任务。

Closing Thoughts

I hope that this article has given you a better picture of how Gradle fits into your development workflow. This took way longer to write that you would think, but it was well worth it for me. I’ve since rewatched the “Speeding Up Your Android Gradle Builds” video and I’m proud to say I’m no longer completely lost by the end of it.

结束时的思考

我希望这篇文章能够让你更好地了解 Gradle 如何适应你的开发流程。为按照你们常规的思考方式来写,这花费了我更长的时间,但是这对我来说是非常值得的。我已经重新看了“加速 Android Gradle 构建”的视频,我很自豪地说,在看完后我不会再完全迷失了。


via:oschina

发表评论

电子邮件地址不会被公开。 必填项已用*标注