preface

For Android developers, Gradle is a familiar stranger. It can be said that I use Gradle every day, but I do not know the principles and details of Gradle

This paper mainly includes the following contents:

  1. GradleWhat is it?
  2. Gradle WrapperWhat is?
  3. AGPWhat is it?
  4. gradle.propertiesWhat is?
  5. settings.gradleWhat is?
  6. build.gradleWhat is?
  7. GradleWhat is the life cycle?

1. GradleWhat is it?

Gradle has been around for a long time. How do you describe Gradle in one sentence? A dependency management framework? A build framework?

GradleIs a run onJVMGeneral-purpose build tools for, its core model is a set ofTaskComposed of directed acyclic graphs (Directed Acyclic Graphs).

2. Gradle WrapperWhat is?

We use it all the timeGradleBut if you think about it, we’re useless in the projectgradleCommand, while the general is usedgradlewCommand, at the same time as shown below, to look through the entire project, withgradleThese are the only folders that matter, and all I find isgradle-wrapper.jar.

What is gradlew and gradle-wrapper.jar?

Wrapper. This is the gradle wrapper. This is true, because Gradle is in a phase of rapid iteration, new releases are often made, and if our project were to reference them directly, it would be very troublesome to change the version and so on. Every project may have a different gradle version, so manually configuring the gradle version for each project can be troublesome. Gradle is designed to make building projects easier. So Android came up with the idea of wrapping, introducing gradle-wrapper, automatically downloading and configuring Gradle for each project by reading the gradle version in the configuration file. We don’t have to worry about how to download Gradle and how to configure it into the project.

Gradlew is run on Linux, MAC, and gradlew. Bat is run on Windows. Gradlew can run gradle commands on the command line. Instead, run Gradlew? Gradle command lines are fickle in the same sense as the wrapper itself, so the wrapper encapsulates the command line. Using the same gradlew command, the Wrapper automatically executes the gradle command for the specific version. Gradlew is the gradle version specified in the project, so it is clearer and clearer

3. AGPWhat is it?

AGP is the Android Gradle Plugin, which is the official development of Android Gradle Plugin. Before understanding AGP, we first introduce what is the plug-in?

Gradle itself is a general-purpose build system that doesn’t know if you’re compiling Java or C. In Java, you need to call javac to compile.java files into.class files, while in C, you need to call GCC to compile.c files into.o files. These build processes are too cumbersome for each developer to manage on their own. A plug-in is a template that compiles some type of template.

AGP is a collection of Gradle plug-ins suitable for Android development. Such as com. Android. Application of AGP plugin provides compileKotlin, compileJava, processResource and a series of Task, and set the dependencies between the Task. It also provides a number of configurable properties. The user only needs to use the plugins {… } Custom Android builds can be implemented by introducing plug-ins that configure a few properties depending on the project. The AGP plug-in can be used to quickly build Android projects, which is the significance of the AGP plug-in. The task list in its execution process is shown below

4. gradle.propertiesWhat is?

Besides Gradlew and AGP, we also often used gradle. The properties, we often in gradle. Peoperties defined in some unified version number, such as minSdkVersion targetSdkVersion, etc., And then pass in each module rootProject. In order to realize the multiplexing minSdkVersion

How does rootProject get the values defined in gradle.properties? The answer is simple. Gradle starts up by default reading gradle.properties and loading its parameters. This is the same as when we run Gradle and pass parameters to it from the command line. Of course, different methods have different priorities. Specify the priority of parameters: Command line parameters > GRADLE_USER_HOME gradle.properties file > project root directory gradle.properties file.

Gradle uses two directories: Gradle User Home contains the global configuration. Gradle User Home contains the global configuration. Gradle User Home contains the global configuration. Global initialization scripts and dependent cache and log files. If build cache is enabled, the build cache is also shared by all projects here. Default: $USER_HOME/.gradle. Project Root Directory The Project Directory stores the content related to the current Project build. For example, incremental compilation cache.

In general, gradle.properties is just a configuration file for parameters that has the same effect as passing parameters on the command line, so it can be read in Project

5. settings.gradleWhat is?

When we run the gradle command in a directory, the convention is to look up two files from the current directory:

  1. settings.gradle(.kts)
  2. build.gradle(.kts)

Settings. gradle: What is settings.gradle? What does it do? All modules that need to be built need to be registered in settings.gradle, so its role is to describe “the module that the current build is participating in “.

Settings. gradle searches in the following order: Starting from the previous directory, stop if settings.gradle(.kts) is found, otherwise recurse to the parent directory. You can register the modules you want to contribute to the build by using the following method in the project name: the delimiter representing the project, similar to the /. In the path. If it starts with:, it is relative to root project

include(":app".":libs:someLibrary")

include(":anotherLibrary")
project(":anotherLibrary").projectDir = File(rootDir, ".. /another-library")
Copy the code

6. build.gradleWhat is?

Gradle is one of the most familiar and commonly used build.gradle, Every module has a build.gradle that configures the build information for the current module. Build. gradle for the root module is called the root build script, and build scripts for other sub-modules are called module Build scripts.

The project construction process is roughly as follows, where init script refers to init.gradle file in $GRADLE_USER_HOME. It mainly performs some initial configuration. The execution process of single-module construction is roughly as follows: Init script -> setting script -> build script init script -> setting script -> root build script -> build script

In general, the root build script is not an actual module, but is used for uniform configuration of submodules, so the root build script will not have much content.

Gradle does not execute the build. Gradle (.kts) file during Initialization. The build script is actually parses during Configuration. But build Script execution is special. Instead of simply executing all the code, it is essentially describing and configuring the build rules in the code, and then executing the tasks according to the rules. The Build script, the most complex configuration script in Gradle, actually does only two things: one is to introduce plug-ins and the other is to configure properties

Plugins can also use version to specify the version of the plug-in and apply to decide whether to apply the plug-in immediately:

plugins {
    id("com.android.application")
    id("com.dorongold.task-tree")   version "1.4"
    id("com.dorongold.task-tree")   version "1.4"   apply false
}
Copy the code

The so-called configuration properties are actually configured for the imported plug-in. Android {… } The DSL property, which is provided by the plugin. Once a plug-in is applied, it can be configured using the DSL provided by the plug-in to influence the building process of that module. To put it another way, the property configuration DSLS provided by these plug-ins act as parameters to the plug-in init function that are ultimately passed into the plug-in. When the build is executed, the current module is compiled based on the configuration.

plugins {
    id("com.android.application")
}

android {
    compileSdkVersion(28) defaultConfig { .... }}...Copy the code

7. GradleWhat is the life cycle?

With that in mind, we can start to understand the Gradle life cycle. Now that we know about Gradle’s lifecycle, we can have an overview of the overall process that Gradle executes, and we can use these lifecycle to do some Hook operations

Unlike the traditional top-down execution of scripts, onceGradleThe build involves multiple files, and the main flow is as follows:

Gradle Execution is divided into three phases: Initialization -> Configuration -> Execution. Each stage has its own responsibilities.

7.1 Initializationphase

The Initialization phase is used to initialize the build. The Initialization phase is divided into two sub-processes: executing the Init Script and executing the Setting Script. Init Script reads the global Script. Get Gradle User Home directory, Gradle version, etc. Setting Script is settings. Gradle

7.2 Configurationphase

After the build completes the Initialization phase, it enters the Configuration phase. This phase starts loading Build scripts for all modules in the project. “Loading” is executing statements in build.gradle(.kts), creating tasks based on script code, and eventually generating dependency graphs based on all tasks. Did we say above that “Gradle Core models are Directed Acyclic Graphs composed of a Task “? The task dependency map is generated at this stage.

It should be noted that the loading sequence of each module in the Configuration stage is out of order, which has nothing to do with dependency relationship and joining sequence

7.3 Executionphase

Once the task dependency graph is completed, Gradle is ready to execute. This is where the compilation and packaging action actually takes place. In the case of Java, the source code is compiled by calling Javac and then packaged as jar. For Android, it’s a little more complicated. These differences come from the plugins we use. In general, start executing tasks

7.4 Life CycleHook

GradleProvides a rich life cycleHook, we can add various according to our needsHooK

Based on the location of the life cycle in the diagram, you can clearly know the “latest registration time of the life cycle “. For example, settingsEvaluated is callback after the setting script has been evaluated, so there is no problem registering in init script and setting script. But if the registration is in the Build script, it doesn’t work.

There are also a few other things to note about lifecycle hooks

  1. projectsLoadedbeforeProjectIt has not been created, so it can only be usedgradlesettingsobject
  2. projectsLoadedThe callback has been based onsetting scriptCreated for each moduleProjectObject, we can refer toprojectObject to set somehook, it isbuild scriptThe configuration information is not available because it has not been configured
  3. Whenever abuild.gradle(.kts)When executed, bothafterEvaluateThe callback representsprojectevaluateFrom then on,projectThe object is complete, that is: currentbuild.gradle(.kts)All configuration items can be accessed.
  4. All of theProjectWhen the configuration is complete, a callback is performedprojectsEvaluated
  5. GradleThe core logic is the basistaskThe directed acyclic graph is then executed in the graphtask.task graphA callback is generatedgraphPopulated
  6. When alltaskWhen it’s done, the build is done, and the callback is calledbuildFinished

conclusion

Gradle is a process of building and packaging Android files. Gradle is a process of building and packaging Android files. Gradle is a process of building and packaging Android files. It is also convenient for us to use Gradle life cycle to do some Hook work to improve development efficiency. If this article has been helpful to you, please like it, comment on it

The resources

Learn the differences between Gradle and Gradle Wrapper