preface

In the first two articles, you’ve learned about the Groovt language, Gradle basic commands, life cycles, tasks, and then you’ll learn about plug-ins and dependency configuration.

A Project,

Build. gradle will generate project instances in the configuration phase, and directly call methods or properties in build.gradle, which actually call methods or properties of the current project project object.

1. API related to Project

  • Project (‘:app’){} specifies the configuration of project(app). The source code is as follows:
/** * <p>Locates a project by path and configures it using the given closure. If the path is relative, it is * interpreted relative to this project. The target project is passed to the closure as the closure's delegate.</p>  * * @param path The path. * @param configureClosure The closure to use to configure the project. * @return The project with the given path. Never returns null. * @throws UnknownProjectException If no project with the given path exists. */ Project project(String path, Closure configureClosure);Copy the code
  1. Allprojects {} configures allprojects and their child projects
allprojects {//fro project include repositories
    repositories {
        google()
        mavenCentral()
    }
}
Copy the code
  1. Subprojects {} configures all subprojects
// build. Gradle subprojects {println("subprojects->$it")} : > Configure project: subprojects->project ':app'Copy the code
  1. Buildscript {} represents the project configuration buildscript classpath
Buildscript {//for * gradle include dependencies and repositories {Google () mavenCentral()} dependencies {// build tool dependency classpath(group: 'com.android.tools.build', name: 'gradle', version: '4.2.1')}}Copy the code

2. Ext extension

You can extend any object property using Ext.

  1. The configuration in the root project is visible to other projects
  2. In general, ext attribute extension is carried out in rootProject to provide reuse attributes for sub-projects, which are directly accessed through rootProject.
  3. You can add properties to any object using Ext: Use closures, in which you define extended properties. Add extended attributes using = assignment directly.
/ / root build. Gradle enclosing ext pop = "pop" / / ext {} / / / pop = '1111'Copy the code

4. Use Gradle. properties to define properties in the form of key-value pairs, which can be used directly by any project.

For example, when managing global dependency configuration files, we usually have a config. Gradle file, which is written as follows:

ext { android = [ compileSdkVersion: 29, minSdkVersion : 21, targetSdkVersion : AndroidxVersion = "1.0.0" supportDependencies = [supportV4: "androidx.legacy:legacy-support-v4:${androidxVersion}", ] }Copy the code

Then import this file in the Module build.gradle and use its properties to achieve dependency versioning.

Second, the plug-in

A plug-in is a package of independent or common code that can be reused by other modules. The application of plug-ins is done through the project.apply () method, and there are two types of plug-ins, one is script and the other is binary.

1. Script plug-in

Plugins are edited directly in gradle script files and then referenced using apply plugin: PluginName. They can only be used in this script.

Class MyPlugin implements Plugin<Project> {@override void apply(Project target) {// This Project object is the apply Plugin's Project object println "MyPlugin apply" } } apply plugin: MyPluginCopy the code

2. Binary plug-in

Binary plugins are plugins that implement the Plugin interface. They have the Plugin ID and are referred to by the Apply ID. This can be done in a separate project, or it can be written in the buildSrc directory. Since buildSrc can be applied to other projects, it needs to be built before its project is initialized, so it will be built before settings.gradle. The plugins in the buildSrc directory, at run time, will be automatically packaged as jars and dependent.

  • Create a moudle and name it buildSrc.
  • Delete the directory only to leave the main folder, and then create the Java folder (groovy works, but the implementation language is different), and the Resources folder.
  • New resources – > meta-inf. Gradle – plugins – > com. Empty. The test. The properties file, and writing
implementation-class=com.empty.test.MyTestPlugin
Copy the code
  • Configure groovy dependencies in buildSrc: apply plugin:’groovy’
  • You can use the apply plugin: MyTestPlugin plugin in your app

Third, the Transform

Transform allows us to manipulate the compiled class file before it is converted into a dex file. Each transform is a Gradle task. The specific implementation is as follows:

class MyTestTransform extends Transform { @Override String getName() { return MyTestTransform } @Override Set<QualifiedContent.ContentType> getInputTypes() { return TransformManager.CONTENT_CLASS } @Override Set<? super QualifiedContent.Scope> getScopes() { return TransformManager.SCOPE_FULL_PROJECT } @Override boolean isIncremental() { return true } @Override void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException { super.transform(transformInvocation) transformInvocation.inputs.each { TransformInput input -> Input. JarInputs. Each {JarInput JarInput Jar} - > / / processing input. DirectoryInputs. Each {DirectoryInput DirectoryInput - > }}}Copy the code
  • GetName () : indicates the corresponding Task name
  • GetInputTypes () : Determines which types of results to convert, often using CONTENT_CLASS to represent the Java class file to process.
  • GetScopes () : Specifies the scope of the plug-in, usually transformManager. SCOPE_FULL_PROJECT to handle all class bytecodes.
  • IsIncremental () : Whether incremental updates are supported
  • Transform () : The actual transformation process

Then register the Transform in the Plugin.

def appExtension = project.getExtensions().getByType(AppExtension.class)
appExtension.registerTransform(new MyTestTransform())
Copy the code

Iv. Dependency management

To configure dependencies, we use common dependencies such as implementation, API, compileOnly, etc. The details are available on the website, linked here.

Note that:

  • A implemetation of B, B implemetation of C
  • A implemetation B, B API C, A implemetation C
  • A implemetation B, B implemetation C, C API D, A implemetation B, B implemetation C, C API D
  • A implemetation of B, B API C, C API D

Classes in these modules are loaded at run time regardless of where ABCD is added to the classpath.

1. View project dependencies

To view project dependencies, use the command: Gradlew :app:dependencies or gradlew :app:dependencies –configuration compile can also be used to see gradlew build –scan on the website.

At the same time, Gradle will also have part of the optimization, for example: if the project has multiple versions of the same dependency library, the highest version is selected by default, Gradle will automatically exclude repeated dependencies, Gradle supports dependency passing by default, and so on.

Among them

  • X.X.X (*) The dependency already exists and will not be repeated.
  • X.X.X -> X.X.X The version of the dependency is replaced by the version indicated by the arrow.
  • X.X.X -> X.X.X (*) The version of the dependency is replaced by the version indicated by the arrow and the dependency already exists.

2. Eliminate dependencies

As the scope of the application grows, it may contain many dependencies, both direct and pass-through (the libraries that the imported libraries in the application depend on). To exclude dependencies that are no longer needed, use the exclude keyword:

Dependencies {implementation (' androidx. Appcompat: appcompat: 1.2.0 ') {exclude (group: 'androidx. Core) exclude (group: 'androidx.arch.core', module: 'core-common') } }Copy the code

Use all exclude:

Configurations {all*.exclude Module: 'name'}Copy the code

3. Specify the version of the dependency library

Use force to forcibly specify the version of a third-party library.

configurations.all {
   resolutionStrategy {
       force 'group:module:version'
   }
}
Copy the code

Publish plug-ins locally

UploadArchives: uploadArchives: uploadArchives: uploadArchives: GroupId is the name of the organization or company,artifactId is the name of the module, and version is the current version number, so Gradle will generate and upload the POM.xml file when executing uploadArchives.

apply plugin: 'maven' uploadArchives { repositories.mavenDeployer { repository(url: uri('.. /repostory')) pom.groupid = "com.empty.test" pom.artifactid = "myLibrary" pom.version = "1.0.0"}} Implementation (group: 'com.empty.test', name: 'myLibrary ', version: '1.0.0')Copy the code

The release remote is usually either MavenCentral or Jitpack, and the implementation can be self-checked.

Six, summarized

At this point, we learned what a project, custom plug-in, Transform, publish plug-in, and dependency configuration are.