Series of articles look here

Gradle gets started and builds the environment

Gradle is an introduction to meta-programming

Gradle: Groovy syntax for getting started

Gradle introduction and lifecycle

Gradle core project

How to create a Gradle plugin by yourself

What is a Transform in Gradle?

preface

/ Gradlew projects prints all the projects under the current project. Specifically, a build.gradle file is a project. The number of projects depends on how many are set in the setting.gradle file. Each project corresponds to an output, which depends on what is in build.gradle.

The Project core API

Under each project there is a build.gradle file. Build. gradle in the root directory manages build.gradle under subprojects. Let’s take a look at the project API.

getAllProjects()

We can print all projects with getAllprojects, which is the same as the./gradlew projects command. Here is an example:

getAllprojects().eachWithIndex { Project entry, int i ->
    if (i == 0) {
        println("RootProject-------${entry.name}")
    } else {
        println("SubProject-------${entry.name}")
    }
}
Copy the code

The following output is displayed:

RootProject-------APMProjetct
SubProject-------apm
SubProject-------app
SubProject-------aspectj
Copy the code

getSubprojects()

This method is to get an instance of all subprojects with the following code:

getSubprojects().eachWithIndex { Project entry, int i ->
        println("SubProject-------${entry.name}")
}
Copy the code

The following output is displayed:

> Configure project :
SubProject-------apm
SubProject-------app
SubProject-------aspectj
Copy the code

getRootProject()

Since we can get all the child nodes, we can still get the root node separately, as shown in the following code:

println("the root project name is ${getRootProject().name}")
Copy the code

The following output is displayed:

> Configure project :
the root project name is APMProjetct
Copy the code

getParent()

This method is used to get an instance of the parent project in the child project. Example code is as follows:

println("the parent project name is ${getParent().name}")
Copy the code

The output results can be imagined:

> Configure project :aspectj
the parent project name is APMProjetct
Copy the code

projects()

Gradle file for the parent project, and do some separate processing for the child project, like this:

project("app") {
    apply plugin: 'com.android.application'
}
Copy the code

allprojects()

The AllProjects representation is used to configure the current project and each of its sub-projects. In AllProjects we usually configure some common configurations, such as the most common global warehouse configuration.

allprojects {
    repositories {
        google()
        jcenter()
    }
}
Copy the code

subprojects()

This method allows us to do some configuration for all the sub-projects, such as this:

subprojects { if(project.plugins.hasPlugin("com.android.library")){ apply from ".. /uploadMaven.gradle" } }Copy the code

Ext extended attributes

We can modify the build.gradle file configuration for other projects by default via ext extension properties. For example, I added the following properties to root Project:

ext {
    minSdkVersion = 21
    targetSdkVersion = 30
}
Copy the code

Then we can modify the build.gralde file in the subproject as follows:

Android {compileSdkVersion 30 buildToolsVersion "30.0.1" defaultConfig {applicationId "com.xxxxx. Apmprojetct" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 1 versionName "1.0" testInstrumentationRunner "androidx. Test. Runner. AndroidJUnitRunner"}}Copy the code

You can also use apply to create a new gradle file. For example, you can create a config. Gradle file.

android {
    signingConfigs {
        debug {
            storeFile file('xxx.jks')
            storePassword 'xxx'
            keyAlias 'xxxx'
            keyPassword 'xxxx'
            v1SigningEnabled true
            v2SigningEnabled true
        }
        release {
            storeFile file('xxx.jks')
            storePassword 'xxx'
            keyAlias 'xxxx'
            keyPassword 'xxx'
            v1SigningEnabled true
            v2SigningEnabled true
        }
    }
}
Copy the code

Then we can use it in engineering like this:

apply from: 'config.gradle'
android {
      buildTypes {
        debug {
            signingConfig signingConfigs.debug
            minifyEnabled false
            shrinkResources false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            versionNameSuffix "_dev"
        }
        release {
            signingConfig signingConfigs.release
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
Copy the code

Gradle file operations

Local files in Gradle can be manipulated using the project.file () method, which specifies the relative or absolute path of the file. For example, we can create a new file, check the absolute path of a file, and determine whether a file exists. The example code is as follows:

// Use the relative path File configFile = File(' SRC /main/ Java /test.java') configfile.createnewFile (); / / to use absolute paths configFile = file ('/Users/XXX/XXX/SRC/main/Java/test. The Java ') println (configFile. AbsolutePath) / / use a file object ConfigFile = file(new file(' SRC /main/ Java /test.java'))Copy the code

The output is as follows:

/Users/xxx/xxx/src/main/java/test.java
true
Copy the code

Document collection

The FileCollection interface is used to represent Gradle files. We can use the project.files () method to obtain a FileCollection object. All file collections are created when needed. Example code is as follows:

FileCollection collection = files('src/test1.txt',
        new File('src/test2.txt'),
        ['src/test3.txt', 'src/test4.txt'])
Copy the code

We can traverse the file like this:

Collection. each {File File -> println file.name}Copy the code

We can also convert files like this:

Set set1 = collection.files Set set2 = collection as Set String path = collection.asPath // Convert the File collection to File File file1 = collection.singleFile File file2  = collection as FileCopy the code

In addition, we can also add or delete a file, for example:

Def union = collection + files(' SRC /test5.txt') def different = collection - files(' SRC /test3.txt')Copy the code

The file tree

You can think of a file tree as a hierarchical collection of files, so a file tree contains operations for all file collections. We can use the project.filetree () method to create a fileTree object, and we can also use overfiltering conditions to include or exclude related files. Example code is as follows:

FileTree tree = FileTree (dir: Include '**/*.java' // Exclude '**/Abstract*' // Use path to create file tree object, Include ('**/*.java') // create fileTree = fileTree(' SRC ') {include '**/*.java'} // Tree = fileTree(dir: 'SRC ', include: '**/*.java') tree = fileTree(dir:' SRC ', includes: ['**/*.java', '**/*.xml']) tree = fileTree(dir: 'src', include: '**/*.java', exclude: '**/*test*/**')Copy the code

Now that we’re talking about creating a file tree, of course, we can also do some business operations on the file tree, such as:

Each {File File -> println File} // Filter to generate new File tree objects FileTree filtered = tree. Matching {include 'org/gradle/ API /**'} // Merge two file trees with the '+' sign, the same as the '+' operation for file sets FileTree sum = tree + FileTree (dir: Visit {element -> println "$element.relativePath => $element.file"}Copy the code

File copy

We can copy A file using the copy task, specify the copy content and filter the copy content, and rename the file during the copy process. Let’s start with A simple example, for example, I need to copy from directory A to directory B, then we can do this:

task copyTask(type: Copy) {
    from 'src/main/java/fileA'
    into 'src/main/kotlin/fileB'
}
Copy the code

Of course, we also support batch copy, such as this:

task copyTask(type: Copy) {// Copy all files in the SRC /main/webapp directory from 'SRC /main/ Java' // Copy a single file from 'SRC /main/res/index.html' // Copy the contents from the Zip file From zipTree(' SRC /main/assets.zip') // into 'SRC /main/mouble'}Copy the code

As mentioned earlier, we can rename the module when we copy it. The most common scenario is when we need to rename the module when we disassemble the project. Then we can do this:

task rename(type: Copy) {from 'moudleA/ SRC /main/res/' into 'moudleB/ SRC /main/res/' // Rename a file with a closure {String fileName -> fileName.replace('moudleA', 'moudleB') } }Copy the code

Significant savings in manual renaming costs. We can also add filter conditions:

task copyTaskWithPatterns(type: Copy) {
    from 'src/main/drawable'
    into 'src/main/drawable-xxhdpi'
    include '*.jpg'
    exclude { details -> details.file.name.endsWith('.png') &&
                         details.file.text.contains('.webp') }
}
Copy the code

Of course, we can also copy and delete the corresponding directory files at the same time, we can operate like this:

Task libs(type: Sync) {from configurations. Runtime} into "$buildDir/libs"}Copy the code

conclusion

In this article we briefly introduced the operations related to projects and how we operate files in Gradle. Of course, gradle also has a core task in addition to projects, which we will cover in the next section.

reference

Gradle automation builds Gradle automation projects

This article was first published on my personal blog: Gradle Core Project

More articles please pay attention to my public number: code nong workplace