Gradle is in urgent need of plugins, hotfixes, and building systems for Android. If you don’t understand Gradle, you won’t be able to accomplish these tasks. So Gradle has to learn.

Almost everything in Gradle is based on these two basic concepts:

  • task
  • project

If you know these two, you will know more than half of Gradle.

First Task

Literally a Task, all events executed in Gradle are executed by Task. Let’s say we create a new Android project and type in its root directory:

gradle tasks -q

Copy the code

You can see the following output (you may need to configure gradle environment variables beforehand, or you can use./gradlew instead) :

In the figure above, you can see that each task in the current project has been listed, and the yellow output represents the description of the current task. -q specifies that gradle log information is ignored. This parameter can be used to mask irrelevant output.

Task declaration format

To declare a task, add task before the task name, for example, declare a Hello task.

task hello

Copy the code

Usually we attach tasks with execution actions called actions, for example

hello.doFirst{
    println "hello first"
}

hello.doLast{
    println "hello last"
}

Copy the code

You can also ship with a closure Configuration, called Configuration, in which you can perform not only assignments but also automatic configurations.

hello {
    println "hello"
}

Copy the code

Task dependent on

Declaring a single task makes little or no sense in actual development, and more often than not, multiple tasks are combined, one dependent on the other, to form a series of task sets.

task hello

hello.doFirst{
    println "hello "
}

task world(dependsOn: "hello") << {
    println "world"
}

Copy the code

Above this code defines two task, when we are on a hello mission, will output the hello, and performs the task of world, because dependsOn statement: “hello,” said the world rely on hello, will first perform the hello, executive world again.

task xxx << {
}

Copy the code

This syntax is equivalent to

task xxx
xxx.dolast {
}

Copy the code

You can create a new text named build.gradle anywhere to practice the task definitions and dependencies described above.

Go on with the Project

Android │ ├─ ├─ ├─ build.├.properties │ ├─ build.├.properties │ ├─ Build └ ─ ─ setting. GradleCopy the code

An Android project is usually made up of the above structures, which have many clever uses that are not known.

Setting. Gradle file

Setting. Gradle can also be used to write code, which many people do not know. The following code is an example of what I described in my last article “Enterprise Android modular Platform design advice”. In setting.gradle file, you can specify a project location.

getLocalProperties().entrySet().each { entry ->
    def moduleName = entry.key
    if (Boolean.valueOf(entry.value)) {
        def file = new File(rootProject.projectDir.parent, "/${moduleName.replace("\\W", "")}/${moduleName.toLowerCase()}")
        if (file.exists()) {
            include ":${moduleName.toLowerCase()}"
            project(":${moduleName.toLowerCase()}").projectDir = file
        }
    }
}

Copy the code

build.gradle

The root gradle file for a project that describes the unified resources of the project, including how the sub-resources are used, the dependency environment of the plug-in, and so on.

Subprojects {apply plugin: 'com.android. Library 'dependencies {compile 'com.xxx.xxx: XXX :1.0.0'}}Copy the code

Usually we will manually compile the AAR for each module, such as the support package. The solution is to declare this dependencies in the subProjects closure of the root gradle file of your project.

Usually when we write compile dependencies, we write something like this:

The compile 'com. Android. Support: appcompat - v7:25.0.0'Copy the code

In Gradle, this is a method call, the essence of which is that the compile() method passes in a map parameter, so the complete version actually looks like this:

Compile group: 'com.android.support' name:'appcompat-v7' version:'25.0.0'Copy the code

In addition, map keys can be used not only by group, name, version, but also by configuration and classifier.

Look at the Task

Groovy is based on Java, but adds a bunch of closures to make it easier to develop build scripts. If you don’t know Groovy, don’t worry, just write it as Java, but Kotlin is best. If you don’t already know Kotlin, I highly recommend you check out my Kotlin Primer series

Each Task can be configured with its input and output. If the output of a Task is the same as the output of the previous Task, the Task will not be executed again. At this point, up-to-date is printed on the command line TO indicate that the result is UP TO DATE. For example, Task:

task transform { ext.srcFile = file('hello.txt') ext.destDir = new File(buildDir, 'generated') inputs.file srcFile outputs.dir destDir doLast { destDir.mkdirs() def ins = new BufferedReader(new FileReader(srcFile)) def stringBuilder = new StringBuilder() def temp while ((temp = ins.readLine()) ! = null) { stringBuilder.append(temp) } def destFile = new File(destDir, "world.txt") destFile.text = stringBuilder.toString() } }Copy the code

If the command is repeated, the system displays an up-to-date command

SAO operation behind

The quickest way to learn about any technology is to look at the source code. Gradle’s source code is located in the SRC directory. / Users/zhangtao /. Gradle/wrapper/dists/gradle – 3.3 – all 55 gk2rcmfc6p2dg9u9ohc3hw9 / gradle – 3.3 / SRC/local to create a new Java project, Import source code to view the code and comments, this is the best learning material.

task hello

Copy the code

In Groovy, method parentheses can be omitted, as can quotes if the type of the string can be inferred

public interface org.gradle.api.Project{ Task task(String name); Task task(String name, Closure configureClosure); } // TaskFactory public TaskInternal createTask(Map<String, ? > args) { }Copy the code

Closures exist to better initialize objects. Like Kotlin, you can omit the parentheses when the closure is the last argument.

Copy a = task(myCopy, type: Copy)
a.from 'resources'
a.into 'target'
a.include('**/*.txt', '**/*.xml', '**/*.properties')

Copy the code

Is equivalent to

task myCopy(type: Copy)

myCopy {
   from 'resources'
   into 'target'
   include('**/*.txt', '**/*.xml', '**/*.properties')
}

Copy the code

That’s the end of this chapter, and the next one will show you how to create a Gradle plug-in that dynamically adds code (including jar packages) to a specified class or to a newly generated class at compile time.

Past review:

  • Google Super full Kotlin learning Wang Fried notes! Kotlin Beginner to Master + Advanced Kotlin Intensive Combat (with Demo)
  • Alibaba internal Jetpack treasure book accidentally leaked! The ultimate classic, the ceiling of Android’s architectural components
  • Big guy is strong, bytedance high workers stay up half a month finishing the “componentized actual combat learning manual”, all is the essence!
  • Bytedance has uploaded an “Android Interview Guide for Interviewers,” and it’s all the best without any nonsense
  • 606 pages of new Android interview questions with answers