带你实现自定义Gradle插件

前言

最近在研究编译插桩的三种方法:AspectJASM以及Redex中的ASM,要使用ASM就须要用插件的形式用在项目中,因此这篇的目的是了解并能本身定义一个Gradle插件。html

网上如今很不少这样的文章,你们能够结合起来看。java

Gradle插件打包了可重用的构建逻辑,能够在许多不一样的项目和构建中使用。api

你能够用你喜欢的编码语言来实现一个自定义的Gradle插件,最终都会编译城jvm字节码。如今能够实现插件的语言有Groovyjavakotlin等。通常来讲,使用java或者kotlin实现的插件将优于使用groovy的相同插件。bash

实现插件的方式有三种,下面我会一一为你们来介绍。闭包

实现方式

Build Script

你能够直接在build.gradle中构建一些简单的插件代码,这样作能够自动编译并包含在构建脚本的类路径中,无需执行任何操做。可是该插件只能用于本项目中,外部不可见。app

class GreetingExtension {
    String message = null

}

class GreetingPlugin implements Plugin<Project> {

    @Override
    void apply(Project target) {
        // 利用利用Extension建立greeting 闭包,用于接受外部传递的参数值
        def extension = target.extensions.create("greeting", GreetingExtension)

        target.task("customPlugin") {
            doLast() {
                println(extension.message)
            }
        }
    }
}

/**
 * 使用 greeting{}要放在 apply plugin 以后,apply plugin会执行apply方法进行绑定操做
 * */
apply plugin: GreetingPlugin

greeting {
    message = "Hi this is a cutstom plugin"
}
复制代码

咱们能够用命令行 或者AS右边的gradle在app中找到customPluginjvm

./gradlew -p app customPlugin --stacktrace
复制代码

看下执行结果是什么:maven

> Task :app:customPlugin
Hi this is a cutstom plugin

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed

复制代码

buildSrc project

将插件源代码放在rootProjectDir/buildScr/scr/main/groovy中,这种的优势在于自动编译项目目录下的buildSrc插件源码,不须要手动指定 classpath。同一项目其余模块也可以使用。缺点就是对于其余项目不可用。第三种方式就解决了这个缺点。ide

这里若是想要了解能够看这里gradle

第三种和这个很相似,区别在于这是一个独立的插件项目,能够供其余项目使用。

Standalone project

这种方式是如今目前大多数在使用的方式。

Android Studio中新建Java Library module customPlugin,用IJ来开发插件会比AS要方便的不少。

用AS中开发插件须要这三步:

  1. 移除java文件。
  2. 增长groovy文件夹,这里放全部插件的代码。
  3. 增长resources文件夹,这用来声明插件指向地址。
  4. 修改build.gradle文件
apply plugin: 'groovy'
apply plugin: 'maven'

repositories {
    mavenCentral()
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation gradleApi() // gradler sdk
    implementation localGroovy() // groovy sdk
}

uploadArchives {
    repositories {
        mavenDeployer {
            //设置插件的GAV参数
            pom.groupId = 'com.lenny.plugin'
            pom.artifactId = 'art'// 这个若是不设置,发布以后应该是com.lenny.plugin.customPlugin
            pom.version = '1.0.3'
            //文件发布到下面目录
            repository(url: uri('../repo'))
        }
    }
}
复制代码

修改后的目录应该是这个样子的:

 ├── build.gradle 
 ├── libs 
 ├── customPlugin.iml 
 └── src     
    └── main
        ├── groovy     
    │          └── com    
    │              └── lenny     
    │                  └── plugin     
    │                      ├── CustomPlugin.groovy     
    │                          
    └── resources         
        └── META-INF             
            └── gradle-plugins                 
            └── com.lenny.plugin.properties


复制代码

CustomPlugin.groovy

package com.lenny.plugin

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

public class CustomPlugin implements Plugin<Project> {
    @Override
    void apply(Project project) {
        println("hello from custom plugin")
    }
}
复制代码

注意文件的后缀。

com.lenny.plugin.properties

implementation-class=com.lenny.plugin.CustomPlugin
复制代码

到这里就算基本完成了,咱们同步下代码,就能够在右侧的Gradle中找到uploadArchives命令,执行该命令以后就会在项目同级目录下发现:

└── repo    
    └── com
        ├── lenny     
    │          └── plugin    
    │              └── art     
    │                  └── 1.0.3     
    │                      ├── art-1.0.3.jar
    │                      ├── art-1.0.3.jar.md5
    │                      ├── art-1.0.3.jar.sha1
    │                      ├── art-1.0.3.pom
    │                      ├── art-1.0.3.pom.md5
    │                      ├── art-1.0.3.pom.sha1
 
复制代码

而后咱们在项目中集成:

工程的build.gradle

buildscript {
    repositories {
        ...
        maven {
            url uri('repo/')
        }
    }
    dependencies {
        ...
        classpath 'com.lenny.plugin:art:1.0.3'
    }
}
复制代码

app的build.gradle

apply plugin: 'com.lenny.plugin'
复制代码

若是是发布在上线的,repositoies中就不这么写了。

classpath xxx的由来:groupId:artifactId:version

apply plugin: 'xxx'中则是properties的前面的:com.lenny.plugin

执行结果:

> Configure project :app
hello from custom plugin

> Task :app:createMockableJar UP-TO-DATE
> Task :app:preBuild UP-TO-DATE
复制代码

总结

这样一遍走下来,是否是以为自定义gradle很好实现嘛,这里只是一个初步的介绍,更高级的用法能够查看官方的文档。

感谢大家看到这里。

参考资料

开发自定义Gradle插件

相关文章
相关标签/搜索