Gradle learning series (3): Gradle plugin

Overview

Started a new series, this series of learning Gradle, the goal is to thoroughly understand Gradle, mainly to make notes that you understand, to prevent forgetting

Gradle series (1): Groovy learning

Gradle learning series (two): Gradle core decryption

Gradle learning series (3): Gradle plugin

Introduction

Gradle itself only provides basic core functions, and other features such as the ability to compile Java source code, the ability to compile Android projects, etc. need to be implemented through plug-ins.
To use plug-ins, you need to plug-in application to the project, by application plug-ins Project.apply()to complete the method.
There are generally two types of plug-ins in Gradle, called 脚本插件and 对象插件.

脚本插件It is an additional build script, which will further configure the build, which can be understood as a normal build.gradle.

对象插件Also called binary plug-in, it is a class that implements the Plugin interface. The following describes how to use them.

Script plugin

For example, we create one in the root directory of the projectutils.gradle

def getxmlpackage(boolean x){
    
    
    def file=new File(project.getProjectDir().getPath()+"/src/main/AndroidManifest.xml");
    def paser = new XmlParser().parse(file)
    return paser.@package
}

ext{
    
    
    getpackage = this.&getxmlpackage
}

This is a simple script plugin, and then reference this script plugin in the app moudle

apply from: rootProject.getRootDir().getAbsolutePath() + "/utils.gradle"

Then you can call the method in the script plugin

Object plugin

Object plug-ins are plug-ins that implement the org.gradle.api.plugins interface. Object plug-ins can be divided into internal plug-ins and third-party plug-ins.

Internal plugin

There are a large number of plugins in the Gradle package, such as the java plugins and c plugins that we often use, we can directly import them

apply plugin:'java'
apply plugin:'cpp'

Three party plug-in

The third-party object plug-in is usually a jar file. If you want the build script to know the existence of the third-party plug-in, you need to use buildscrip to set it.
Define the original warehouse where the plugin is located and the dependencies of the plugin in buildscrip, and then configure it through the apply method. The Android Gradle plugin is also a third-party plugin. If we want to introduce the Android Gradle plugin, we can write:

buildscript {
    
    
    repositories {
    
    
    	//配置仓库
        google()
        jcenter()
    }
    dependencies {
    
    
    	//配置插件依赖
        classpath 'com.android.tools.build:gradle:3.5.3'
    }
}
//然后就可以在需要的地方引入android 插件了
apply plugin: 'com.android.application'

Custom object plugin

Customizing a plug-in is mainly to implement org.gradle.api.Plugin

Build script

This method writes the plug-in code directly in the build script, but this method can only be used in this file, for example, I directly add the following code in the app’s build.gradle

class myPlugin implements Plugin<Project>{
    
    
    @Override
    void apply(Project project) {
    
    
        println("myPlugin 执行了")

        project.task("myTask"){
    
    
            doLast {
    
    
                println("myTask执行了")
            }
        }
    }
}

Then import the plugin defined in this file

apply plugin: myPlugin

This is to implement a plug-in directly in build.gradle, define a MyTasktask in the plug-in , but this plug-in can only be used in this file, we directly perform the Mytasktask./gradlew MyTask

> Task :mylibrary2:myTask
myTask执行了
执行阶段,task ':mylibrary2:myTask'耗时:1ms

We generally don’t use the plug-ins implemented in this way, because this way is too restrictive and can only be used in this project, but not in other projects.

buildSrc project

buildSrc is the default plug-in directory of Gradle. This directory will be automatically recognized when Gradle is compiled, and the code in it will be compiled into a plug-in.

  • First create a named buildSrcjava Module, then only keep build.gradleand the src/maindirectory, delete all others, pay attention to the name must be buildSrc, otherwise the plug-in will not be found

  • Then modify the content in Gradle

apply plugin: 'groovy'  //必须
apply plugin: 'maven'

dependencies {
    
    
    implementation gradleApi() //必须
    implementation localGroovy() //必须
    //如果要使用android的API,需要引用这个,实现Transform的时候会用到
    //implementation 'com.android.tools.build:gradle:3.3.0'
}

repositories {
    
    
    google()
    jcenter()
    mavenCentral() //必须
}

//把项目入口设置为src/main/groovy
sourceSets {
    
    
    main {
    
    
        groovy {
    
    
            srcDir 'src/main/groovy'
        }
    }
}
  • Create an entry directory, create a code entry directory under src/main, as follows:

  • Then implement the plug-in code Text.groovy, pay attention to the file suffix groovy, the file should be importedpackage com.renxh

package com.renxh

import org.gradle.api.Plugin
import org.gradle.api.Project

class Text implements Plugin<Project>{
    
    
    @Override
    void apply(Project project) {
    
    
        println("执行自定义插件")
        project.task("haha"){
    
    
            doLast{
    
    
                println("执行自定义插件 haha task")
            }
        }
    }
}
  • Next main, create a resourcesdirectory under the resourcesdirectory, create a META-INFdirectory under the META-INFdirectory, create a gradle-pluginsdirectory under the gradle-pluginsdirectory, and create a propertiesfile under the directory
  • propertiesThe file can be named by yourself, but it must .propertiesend, such ascom.renxh.plugin.properties
  • Finally, we need propertiesto specify the class that we implement the plug- in in the fileimplementation-class=com.renxh.Text

So far our plug-in project has been written, introduce the plug-in we wrote in the module apply plugin:'com.renxh.plugin', and then execute the task of the plug-in,./gradlew haha

Output

> Task :mylibrary:haha
执行自定义插件 haha task
执行阶段,task ':mylibrary:haha'耗时:0ms

This form of writing can be used in the modules of our entire project, but it is only limited to this project and cannot be used in other projects.

Custom module, upload maven

The second way to write plug-ins can only be used in this project, while other projects cannot be used. Sometimes we need a plug-in to be used in multiple projects, then we need to upload the plug-in to maven

  • First create one java module, the name can be arbitrary, only keep build.gradleand src/main, other files are deleted
  • Modify the content in Gradle
apply plugin: 'groovy'  //必须
apply plugin: 'maven'  //要想发布到Maven,此插件必须使用


dependencies {
    
    
    implementation gradleApi() //必须
    implementation localGroovy() //必须
}
repositories {
    
    
    mavenCentral() //必须
}


def group='com.renxh.cusplugin' //组
def version='2.0.0' //版本
def artifactId='myplugin' //唯一标示


//将插件打包上传到本地maven仓库
uploadArchives {
    
    
    repositories {
    
    
        mavenDeployer {
    
    
            pom.groupId = group
            pom.artifactId = artifactId
            pom.version = version
            //指定本地maven的路径,在项目根目录下
            repository(url: uri('../repos'))
        }
    }
}

Compared with the buildSrcsolution, this adds Maven support and uploadArchivessuch a task. The role of this task is to package and upload the local plug-in to the local maven warehouse. This ../reposmeans the repos under the project root directory. The two .rollbacks twice, and rollback to the project Root directory

In src/maingenerating groovyfile and generating propertiesa file and the step of buildSrcprogramming convergence

Write a plug-in

class CustomPlugin implements Plugin<Project>{
    
    

    @Override
    void apply(Project project) {
    
    
        project.task("cusplugin"){
    
    
            doLast{
    
    
                println("cusplugin任务执行111")
            }
        }
    }
}

Then execute the ./gradlew CusPlugin:uploadArchivesuploadArchives task, and then you can arrange the repos directory to the project root directory, as shown in the figure:

reposDirectory is a local Mavenwarehouse, com/renxh/cuspluginis specified in the script group, mypluginis specified in the script module name, is a unique identifier, the script is 1.0.0version

  • After generating the local maven repository, you need to reference the plugins in the local maven repository. First, you need to add the following to the build.gralde in the root directory:

buildscript {
    
    
    repositories {
    
    
        google()
        jcenter()
        //引入本地仓库
        maven {
    
    
            url uri('./repos') //指定本地maven的路径,在项目根目录下
        }
    }
    dependencies {
    
    
        classpath 'com.android.tools.build:gradle:3.5.3'
        //引入本地仓库中的插件依赖
        classpath 'com.renxh.cusplugin:myplugin:1.0.0'

        
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }


}
  • The path format specified by classpath is as follows:

These three parameters are build.gradleconfigured in the script when the warehouse is generated

classpath '[groupId]:[artifactId]:[version]' 
  • After configuration, it can be used in the module
apply plugin: 'com.android.application'
apply from: rootProject.getRootDir().getAbsolutePath() + "/utils.gradle"
apply plugin:'com.renxh.cusplugin'
  • Finally, you can perform the tasks in the plugin ./gradlew app:cusplugin
> Task :app:cusplugin
cusplugin任务执行111
执行阶段,task ':app:cusplugin'耗时:0ms

Extension of the plug-in

We can also configure parameters for the plug-in when the plug-in is running. The plug-in Extensionis used to pass the parameters back to the plug-in

Below I will add to the above plug-inExtension

First build an entity class to receive parameters

package com.renxh.cusplugin
class MyExtension {
    
    
    String name;
    int age;
}

Then go to the plugin class to add the extension

class CustomPlugin implements Plugin<Project>{
    
    

    @Override
    void apply(Project project) {
    
    
		//添加扩展
        project.extensions.add('myextension',MyExtension)

        project.task("cusplugin"){
    
    
            doLast{
    
    
                println("cusplugin任务执行111")

                MyExtension extension = project.myextension
                //3.输出插件扩展属性
                println ">>>>>> name: ${extension.name} age:${extension.age}"
            }
        }
    }
}
  • Add the customized entity class to the extension through project.extensions.add and give it a name
  • Then get the extended entity class by the name
  • Finally get the attributes in the extension

Re-upload maven after modification

After uploading, you can use the extended entity class in the module

apply plugin: 'com.android.application'
apply from: rootProject.getRootDir().getAbsolutePath() + "/utils.gradle"
apply plugin:'com.renxh.cusplugin'

myextension{
    
    
    name 'renxh'
    age 27
}

Finally execute the task in the plugin,./gradlew app:cusplugin

> Task :app:cusplugin
cusplugin任务执行111
>>>>>> name: renxh age:27
执行阶段,task ':app:cusplugin'耗时:2ms

reference

3 ways to customize Gradle plugins for Android

Custom plugin for Gradle

Guess you like

Origin blog.csdn.net/qq_34760508/article/details/114639713