Android Gradle构建流程浅析

概述

Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建开源工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,目前也增加了基于Kotlin语言的kotlin-based DSL,抛弃了基于XML的各种繁琐配置。它通过组织执行一系列的Task来完成自动化的构建,减少构建项目时的复杂度,而Android Studio也使用Gradle作为基础的构建工具。

Gradle 项目结构分析

在了解Gradle build的生命周期之前,先简单说一下Gradle的项目层次,新建一个Android工程,可以看到项目的结构大致如下
Android Gradle构建流程浅析_第1张图片
Gradle的实质是配置脚本,执行一种类型的配置脚本时就会创建一个关联的对象,譬如执行build.gradle脚本就会创建一个Project对象,这个对象其实就是Gradle的代理对象

settings.gradle

settings.gradle是用于配置整个项目结构的脚本,对应Gradle中的Settings对象,其中最常用的几个方法:

include ':app'
project(':app').projectDir = new File("./...") // 可以指定子模块的目录位置
rootProject/build.gradle

位于项目根目录的build.gradle脚本,负责项目整体的配置,对应一个Project对象,其中最常用的几个方法

buildscript {
      // 配置构建脚本
    repositories {
      // 构建脚本的仓库
        google()
        jcenter()
    }
    dependencies {
      // 构建脚本的依赖,默认依赖Android Gradle Plugin,也可以添加自定义的Plugin
        classpath "com.android.tools.build:gradle:3.6.0"
    }
}
allprojects {
     
    repositories {
     
        google()
        jcenter()
    }
}

mudule/build.gradle

位于子模块的build.gradle脚本,负责这个模块的配置,也对应一个Project对象,类似根目录的build.gradle。

// 引入Android Gradle Plugin,如果是library,引入'com.android.library'
apply plugin: 'com.android.application'

android {
     
    // 配置编译相关的内容
    compileSdkVersion 29
    buildToolsVersion "29.0.2"
    defaultConfig {
     
        applicationId "com.ithe.demo.gradle"
        minSdkVersion 23
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    // 根据编辑类型(Debug/Release)来配置一些编译属性
    buildTypes {
     
        release {
     
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
     
    // 添加模块相关的依赖
}

Gradle的三种主要对象如下:

  • Gradle对象:构建初始化时创建,整个构建执行过程中只有这么一个对象,一般很少去修改这个默认配置脚本
  • Settings对象:每个settings.gradle会转换成一个Settings对象
  • Project对象:每个build.gradle会转换成一个Project对象

Gradle 构建生命周期

Gradle build的生命周期主要分为三大部分:初始化阶段,配置阶段和执行阶段,可参考官方文档:Gradle Build Lifecycle

初始化阶段(Initialization)

Gradle支持单工程或者多工程构建,初始化阶段的任务是确定有多少工程需要构建,创建整个项目的层次结构,并且为每一个项目创建一个Project实例对象。

如果是多工程构建,一般都会在根工程目录下声明一个settings.gradle脚本,在脚本中include所有需要参与构建的子工程,通过解析settings.gradle脚本,读取include信息,确定有多少个Project需要构建。

配置阶段(Configuration)

配置阶段的主要任务是生成整个构建过程的有向无环图

确定了所有需要参与构建的工程后,通过读取解析各个工程对应的build.gradle脚本,构造Task任务,并根据Task的依赖关系,生成一个基于Task的有向无环图TaskExecutionGraph

执行阶段(Execution)

通过读取配置阶段生成有向无环图TaskExecutionGraph,按顺序依此执行各个Task,像流水线一样,一步一步构建整个工程,这也是构建过程中最耗时的阶段。

以下图片来自网络,可以看到,整个 Gradle 生命周期的流程包含如下部分。

Android Gradle构建流程浅析_第2张图片

生命周期监听

同时可以通过gradle或project对象添加Listener,监听不同执行节点。

gradle.addBuildListener(new BuildListener() {
     

    @Override
    @Deprecated
    void buildStarted(Gradle gradle) {
     
        // Called when the build is started
        println("---buildStarted---")
    }

    @Override
    void settingsEvaluated(Settings settings) {
     
        // Called when the build settings have been loaded and evaluated.
        // The settings object is fully configured and is ready to use to load the build projects.
        println("---settingsEvaluated---")
    }

    @Override
    void projectsLoaded(Gradle gradle) {
     
        // Called when the projects for the build have been created from the settings.
        // None of the projects have been evaluated.
        println("---projectsLoaded---")
    }

    @Override
    void projectsEvaluated(Gradle gradle) {
     
        // Called when all projects for the build have been evaluated.
        // The project objects are fully configured and are ready to use to populate the task graph.
        println("---projectsEvaluated---")
    }

    @Override
    void buildFinished(BuildResult result) {
     
        // Called when the build is completed.
        // All selected tasks have been executed.
        println("---buildFinished---")
    }
})

执行编译,可以看到控制台输出如下日志:

Starting a Gradle Daemon (subsequent builds will be faster)
---settingsEvaluated---
---projectsLoaded---
---projectsEvaluated---
---buildFinished---

增加如下代码

gradle.addProjectEvaluationListener(new ProjectEvaluationListener() {
     
    @Override
    void beforeEvaluate(Project project) {
     
        // This method is called immediately before a project is evaluated.
        println("---beforeEvaluate---" + project.name)
    }

    @Override
    void afterEvaluate(Project project, ProjectState state) {
     
        // This method is called when a project has been evaluated,
        // and before the evaluated project is made available to other projects.
        println("---afterEvaluate---" + project.name)
    }
})

输入结果:

---settingsEvaluated---
---projectsLoaded---

> Configure project :
---beforeEvaluate---GradleDemo
---afterEvaluate---GradleDemo

> Configure project :app
---beforeEvaluate---app
---afterEvaluate---app
---projectsEvaluated---
---buildFinished---

其他还有很多Listener,可以看名字联想

    /**
     * Adds the given listener to this build. The listener may implement any of the given listener interfaces:
     *
     * BuildListenerorg
     * TaskExecutionGraphListener
     * ProjectEvaluationListener
     * TaskExecutionListener
     * TaskActionListener
     * StandardOutputListener
     * TestListener
     * TestOutputListener
     * DependencyResolutionListener
     * 
     * @param listener The listener to add. Does nothing if this listener has already been added.
     */
    void addListener(Object listener);

希望通过阅读能够对整个构建流程有个大概了解即可。

你可能感兴趣的:(gradle,android)