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 MyTask
task in the plug-in , but this plug-in can only be used in this file, we directly perform the Mytask
task./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
buildSrc
java Module, then only keepbuild.gradle
and thesrc/main
directory, delete all others, pay attention to the name must bebuildSrc
, 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 suffixgroovy
, 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 aresources
directory under theresources
directory, create aMETA-INF
directory under theMETA-INF
directory, create agradle-plugins
directory under thegradle-plugins
directory, and create aproperties
file under the directory properties
The file can be named by yourself, but it must.properties
end, such ascom.renxh.plugin.properties
- Finally, we need
properties
to 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 keepbuild.gradle
andsrc/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 buildSrc
solution, this adds Maven support and uploadArchives
such a task. The role of this task is to package and upload the local plug-in to the local maven warehouse. This ../repos
means the repos under the project root directory. The two .
rollbacks twice, and rollback to the project Root directory
In src/main
generating groovy
file and generating properties
a file and the step of buildSrc
programming 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:uploadArchives
uploadArchives task, and then you can arrange the repos directory to the project root directory, as shown in the figure:
repos
Directory is a local Maven
warehouse, com/renxh/cusplugin
is specified in the script group
, myplugin
is 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.gradle
configured 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 Extension
is 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