Welcome to follow my official account, scan the qr code below or search the official id: MXSZGG

This article is based on Android Gradle Plugin 3.0.1

  • Gradle is introduced
  • How to learn Gradle
  • Gradle task
  • Gradle build cycles
    • Hook Gradle build process
  • later
    • The appendix

Gradle is introduced

I think most readers of this article will probably know what Gradle is used for, so there’s no need to introduce it, because it’s embarrassing to say a lot of jargon that people don’t understand. In short, Gradle is a powerful tool for most Android developers, providing a convenient way to build apps. If you want to see a richer introduction, you can see how to understand Gradle in a simple way.

How to learn Gradle

I will write a series of Gradle articles next, but teaching people to fish is better than teaching them to fish

  • Gradle is based on the Groovy language. Of course, for lazy programmers like me, I usually choose to search some Chinese articles, such as the appendix Gradle from getting started to Practical – Groovy foundation. The good news is that Groovy, like Java, is based on the JVM, so it’s not that difficult to understand, and there really isn’t much to learn for everyday development.

  • Gradle DSL learning. Create a new Android project and see something in the project/build.gradle file that looks something like this:

    buildscript {
    	repositories {
    	    jcenter()
    	}
    	dependencies {
    	    classpath 'com. Android. Tools. Build: gradle: 3.0.1'
    	}
    }
    	
    allprojects {
    	repositories {
    		jcenter()
    	}
    }
    
    task clean(type: Delete) {
        delete rootProject.buildDir
    }
    Copy the code

If you want to know what buildScript and AllProjects mean, you should click the link above. For example, the documentation states that AllProjects is for configuring the current project and all of its subprojects, and that this method will execute the given closure in these projects. The meaning of the code closure is also available in the documentation.

  • Android Plugin DSL learning. Create a new Android project and see something like this in the project/app/build.gradle file:

    apply plugin: 'com.android.application'
    
    android {
        compileSdkVersion 27
        defaultConfig {
            applicationId "com.joker.cliptest"
            minSdkVersion 21
            // ...
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }
    
    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
        implementation 'com. Android. Support: appcompat - v7:27.1.1'
        // ...
    }
    Copy the code

So what does buildTypes mean, for example, can be found in the documentation above.

  • Gradle Task learns. There is a final one in the project/build.gradle file mentioned earlier

    task clean(type: Delete) {
        delete rootProject.buildDir
    }
    Copy the code

It is actually a task, and more about the pose of the task will be explained in a later section.

In front of a total of four, and looks every bit need to spend a certain amount of time to learn, actually otherwise, wait until the problem met again go to check the document, especially the aforementioned two DSL learning, actually everyday development has been able to understand the meaning of them, namely their is some closures, some fixed format, Because they are in a fixed format, tasks can read the data and do the things they need to do, so you don’t have to worry about Gradle being expensive to learn.

Gradle task

In daily development, of the four points mentioned in the previous section, Gradle Task is most closely related to the development of most developers. In daily development, developers will inevitably carry out build/clean Project, build APK and other operations

In fact, the underlying implementation of these buttons is done through Gradle Task, but the IDE uses the GUI to make it easier for developers to use. Of course, if you look carefully enough, you can see that clicking the corresponding button will output the corresponding information in the Build output bar

A task is a function. There is nothing mysterious about it. To find out what tasks are available in the current Android project, type in the project directory:

./gradlew Tasks (Mac, Linux)

Gradlew Tasks (Windows, same as below)

Will output information similar to the following:

This is only part of the task. If you want to see all tasks, add the –all argument:

./gradlew tasks –all

To the last Other Task:

You can see all the tasks, and the experienced readers may feel more friendly, extract some tasks below:

  • compileDebugJavaWithJavac: Compiles Java files
  • processDebugManifest: Generates the final AndroidManifest file
  • compileDebugAidl: Compiles AIDL files
  • packageDebug: Package as APK

And if to release package opens the confusion, but see also transformClassesAndResourcesWithProguardForRelease task, namely to release package confusion.

These tasks actually run through the developer’s daily development process, but the IDE wraps a layer on top of it, and developers do them at the touch of a button. Of course, some readers may wonder, where do these tasks come from? Why don’t you see any clues in build.gradle? These task is in the plugin, in build. Gradle at the top of the apply of the plugin (. Com. Android application/com. Android. The library). In the following articles, I will explain how to find the source code of these tasks, how to read them, how to write tasks, how to write the plugin, and how to parse the source code of the well-known Gradle plugin. This is exactly why Android developers learn gradle.

Gradle build cycles

Gradle Build cycles are divided into Build Phases and Settings File

  • Initialization: Gradle supports both single and multiple project builds. During the Initialization phase, Gradle determines which projects will participate in the build and creates an instance of a Project object for each Project. For Android projects this is done by executing the setting.gradle file. Setting. gradle = “a module b module” and “A module B module”

    include ':app'.':a'.':b'
    Copy the code

So Gradle will create a Project object instance for each of them.

  • Configuration: This is the phase in which the project configures objects, and the build scripts for all projects are “executed” so that the dependencies between tasks are known. It should be noted that the use of “execution” here may be slightly ambiguous:

    task a {
    
    }
    
    task testDependsOn () {// execute dependsOn() on a task"a")
    	println 'I'm going to do both Configuration and Execution.'
        doFirst {
          println 'I'm only going to execute in the Execution phase of testBoth'
        }
        doLast {
          println 'I'm only going to execute in the Execution phase of testBoth'}}Copy the code

    DependsOn (” A “) and println are implemented in the Configuration for the task closure. The doFirst {}/doLast {} closure is executed during Execution (doFirst {}/doLast {}). These Listeners are only executed during the current task Execution phase.

    Please copy and paste this task into your app build.gradle. Then observe the result of clicking the Sync button in Android Studio (including the Configuration phase) and typing./gradlew app:testBoth on the command line (testBoth Execution phase). You can understand how the closure content is executed. Of course, you can also see the example in Settings file to understand.

    For Android projects, this means executing build.gradle files under each module. In this way, the dependencies of tasks in each build.gradle file are confirmed (for example, the execution of assembleDebug task depends on other tasks being executed first, and this dependency is determined in the Configuration phase).

  • Execution: The Execution stage of a task. The contents of the doFirst {} closure are executed first, and the contents of the doLast {} closure are executed last.

When you execute a task on the command line, you can see the execution flow clearly:

Hook Gradle build process

On the command line, type./gradlew XXX and press Enter to execute the above process, which is further impressed by an in-depth understanding of Gradle for Android

However, in the Gradle development I have encountered so far, the above hook series is rarely mentioned. The most commonly used task is doFirst {}/ doLast {}, and the hook of the Project at the end of the Configuration stage. Gradle file for each Project will be executed during the Configuration phase. How to listen for each point after the Project is introduced? Through the Project. AfterEvaluate — —

//afterEvaluate { Project project ->
//  println 'hook afterEvaluate'
//}

task hook { Project project ->
  afterEvaluate {
    println 'hook afterEvaluate'}}Copy the code

So why hook the afterEvaluate stage of a Project? For example, if you want to print a message before an assembleDebug task, write the following code in app/build.gradle:

// task badHook {
//   tasks.findByName("assembleDebug").doFirst {
//     println 'hook afterEvaluate from BadHook'
//   }
// }

task assDHook {
  afterEvaluate {
    tasks.findByName("assembleDebug").doFirst {
      println 'hook afterEvaluate from assHook'}}}Copy the code

The assembleDebug task is called in the Initialization and Configuration phases. When appProject reaches afterEvaluate, all tasks in appProject will be retrieved, including assembleDebug task. Adding a doFirst {} closure to it will do the trick. Things like badHook closures are executed during Initialization, and appProject doesn’t get all the task information, which will cause assembleDebug not to be found at all.

later

Knowledge base and summarized in this article, the basic situation of writing in the article are outside chain, because the author thinks that there are lots of articles written by very good, so I don’t want to big ink writing, the author got some think is important point for later stage, in addition, this paper has a lot of outside the chain is outside the chain to the official documents, Therefore, readers are advised to consult the documentation when encountering problems. You can read more basic Gradle information in the appendix below:

The appendix

  • Push for in-depth understanding of Android Gradle
  • What you Need to know about Android Gradle
  • Gradle from getting started to getting started – Groovy basics
  • Gradle Android Plugin User Guide
  • ASOP Gradle source

I created a group, if you have any questions about this article or want to discuss Android technology with me, feel free to join.