Android-Gradle系列入门篇

48次阅读

共计 4249 个字符,预计需要花费 11 分钟才能阅读完成。

接下来的一段时间会对 Android Gradle 的相关知识进行梳理,所以借此整理成一个系列。如果你是刚入行的新秀,那么这个系列将会非常适合你,因为 Android 基本的配置都与 Gradle 有关。当然如果你已经入行,但对 Gradle 还是停留在表面的认知上,这个系列也会对你有所帮助。

这篇文章定义为入门篇,将结合自己刚开始学习 Android 时的疑惑与现在对 Gradle 的认识,进一步整理 Gradle 在 Android 中的整体结构。

思考

当我使用 Android Studio 时,一直有几个疑问围绕着我:

  1. Android Studio 是怎样将 Java 与 Kotlin 代码的编译成 APK 文件?
  2. Gradle 是怎样将 Java 与 Kotlin 代码编译成 APK 文件?

后来知道 Android Studio 自身是不能够编译成 APK 的,它是集成了 Gradle。通过研究 Gradle,发现 Gradle 也只是一个构建工具,真正编译成 APK 的功能是由 Android app plugins 提供的。Gradle 只是自动化构建工具,提供构建时的各种生命周期,例如:building、testing、publishing 等。所以 Gradle 不仅支持 Android 还支持 C /C++、Scale 等。

而这个 plugin 其实就是在 project 中的 build.gradle 中声明的 classpath

buildscript {
    repositories {
        // Gradle 4.1 and higher include support for Google's Maven repo using
        // the google() method. And you need to include this repo to download
        // Android Gradle plugin 3.0.0 or higher.
        google()
        ...
    }
    dependencies {classpath 'com.android.tools.build:gradle:3.4.0'}
}

所有每次对 Android 构建进行了优化,我们都要来更新这个版本。

Scripts

有了上面的基础,当我们新建一个 Android 项目时,你将会看到如下与 Gradle 相关的文件:

你会看到文件名几乎都有 gradle 字段,下面我会一一介绍它们的作用

Gradle Wrapper

首先是 gradle-wrapper.properties 文件,打开它你将会看到如下类似信息

#Sat Jan 19 08:25:46 CST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip

这个是 gradle 版本的配置项,申明你当前项目中使用的 gradle 版本。当我们构建项目的时候,它会根据版本自动下载。并且保存到你的电脑本地中。如果你使用的是 Mac,你可以使用如下命令查看你的所有已经下载的 gradle 版本。

ls ~/.gradle/wrapper/dists/

所以如果你不满意当前版本,也可以通过查看 version of Gradle 修改到相应的版本

settings.gradle

这个文件是项目与其子项目或者 module 间的配置。里面通过 include 函数来告诉该项目所包换的子项目或者依赖的 module。例如刚新建项目时只有一个 app 子项目。

include ':app'

所以 settings.gradle 是位于 project 的最外层,即与 app 同级。

build.gradle

现在我们已经知道一个 project 可以包含一个或者多个 sub-projects,而 Android 一般会将 sub-projects 当做 module,所以你会在这看到两个 build.gradle。根据后面的 hint 提示,发现它们分别来自与 project 与 module。

首先我们来看 project 中的 build.gradle,即位于根目录下的文件

buildscript { //1
 
    ext.objectboxVersion = '2.3.0' //4
      
    repositories { //2
        google()
        jcenter()}
    dependencies { //3
        classpath 'com.android.tools.build:gradle:3.3.2'
        classpath "io.objectbox:objectbox-gradle-plugin:$objectboxVersion"        
    }
 
}
 
allprojects { //5
    repositories {google()
        jcenter()}
}
 
task clean(type: Delete) { //6
    delete rootProject.buildDir
}
  1. buildscript 闭包是申明编译该项目所需的相关配置
  2. 告知 gradle 这些配置将从 google() 与 jcenter() 中获取
  3. 申明相关的 plugin,例如 Android Plugin for Gradle。
  4. 在 gradle 中有一个 extra property 属性,允许我们通过它来申明一些变量,例如 plugin 的版本号。有一个特性就是这些变量在 gradle 中都是全局的。所以对于多个 module 时,我们可以通过它来统一相关的版本号。最后在 3 中通过 ${name} 来引用
  5. 因为可能有多个 sub-project,对于一些相同的配置,可以通过 allprojects 来进行统一管理。
  6. 申明一个 task,用来执行相关任务,这里是 clean 操作,目的是删除 build 文件夹中的数据

下面是 module 中的 build.gradle

apply plugin: 'com.android.application'
apply plugin: 'io.objectbox' //1
 
android { //2
    compileSdkVersion 28
    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 27
        versionCode 100005
        versionName "1.0.5"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
       release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
 
dependencies { //3
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support:support-v4:28.0.0'
}
  1. 通过调用 apply 函数,引入我们需要依赖的 plugin,这个就是我们在根 build.gradle 中申明的 classpath
  2. android 闭包是 gradle 最重要的配置申明,例如默认的配置信息 defaultConfig,包含 minSdkVersion 最小支持的 android 版本,versionCode 与 versionName 等。这些配置都与编译息息相关,最好你应该熟悉它们。你实在记不住的话,我这里也有秘籍,AppExtension 这里面包含所有的配置项与所代表的意义。
  3. 这里的 dependencies 用来申明项目所依赖的第三方库,而这些库的获取来源无需再次申明,因为我们已经在之前的根目录的 build.gradle 中的 allprojects 闭包中进行了申明。再者之前的 ext 全局变量也可以在这里使用。

gradle.properties

这个文件一般都是本地文件,主要用来对 gradle 构建的一些个人配置项。例如 gradle 运行是否并行,gradle 的 jvmargs 大小、是否开启 daemon 等等。它会在 gradle 运行时注入到相应的 build.gradle 中。

local.properties

这个文件也是本地文件,只不过它用来配置 gradle 之外的配置信息,例如 ndk 与 sdk 目录,或者一些敏感的信息,例如插件开发打包上传到远程仓库这时可能需要账号、密码、api_key 等,防止打包时暴露。

Gradle Tasks

gradle tasks 是用来执行特定的 gradle 任务的。我们可以直接点击 Android Studio 右边的 Gradle 按钮,你会发现在 Tasks 下会列出该项目的所用可执行的 gradle 任务。

或者你也可以在命令行中执行如下命令,查看 app 下的所有 tasks

./gradlew app:tasks

我们顺便点击一个,例如 assembleDebug,我们将会在 Run 日志系统中看到如下执行结果

根据输出的日志,也标明它是执行了 task: assembleDebug

当然我们也可以在命令行执行指定的 task,例如要达到上面相同的效果,我们可以输入如下命令

./gradlew assembleDebug --console plain
  1. ./gradlew 代表的是使用 Gradle Wrapper 中的 gradle,就是该项目本身的 gradle 版本,避免直接使用 gradle 命令
  2. assembleDebug 是 task 的名称
  3. –console plain 输出完整的日志

既然说到这里,再说一个初级者容易做的无意义的操作。有时会碰到一些问题而去点击 Clean Project,再点击 Rebuild Project。其实 Clean Project 是不必要的。我们可以直接先点击 Rebuild Project,查看日志

结果是它分别执行了 task: clean,assembleDebug。所以 Rebuild Project 就已经包含了 Clean Project,我们无需多此一举执行 Clean Project。

嗯,就这些。最后,希望这篇文章,能够让大家对 gradle 在项目中的结构与所处的地位有一个更清晰的理解。

想更多的了解我,亦或者对我的文章感兴趣的可以关注我的公众号,及时获取最新动态~

正文完
 0