美文网首页Android开发Android进阶之光Android开发经验谈
Gradle核心思想(六)自定义Gradle插件的三种方式

Gradle核心思想(六)自定义Gradle插件的三种方式

作者: 刘望舒 | 来源:发表于2019-04-05 01:48 被阅读4次

    本文首发于 公众号 刘望舒
    相关文章
    Gradle核心思想(一)为什么现在要用Gradle?
    Gradle核心思想(二)Gradle入门前奏
    Gradle核心思想(三)Groovy快速入门指南
    Gradle核心思想(四)看似无用,实则重要的Gradle Wrapper
    Gradle核心思想(五)通俗易懂的Gradle插件讲解

    前言

    在上一篇文章Gradle核心思想(五)通俗易懂的Gradle插件讲解中,我介绍了什么是Gradle插件、如何使用Gradle插件、Gradle插件的作用和好处,由于篇幅的原因,还有一个重要的知识点没有讲,那就是自定义Gradle插件(自定义Gradle对象插件)。自定义Gradle插件主要有三种方式,分别是build.gradle中编写、buildSrc工程项目中编写、独立项目中编写。建议阅读本文前,先阅读开头列出的本系列相关文章。

    1.build.gradle

    对象插件是实现了org.gradle.api.plugins<Project>接口的插件,这个接口中只定义个一个简单的apply方法,想要实现自定义插件就需要去实现org.gradle.api.plugins<Project>接口。
    Groovy、Java、Kotlin都可以作为实现插件的语言,在本文的示例中,使用Groovy作为实现语言。
    在实际工作中我们很少会在build.gradle中编写自定义插件,这里是为了带大家写个最简单的例子,可以最快最直接的了解什么是自定义插件。

    1.1 简单的自定义插件

    这里使用IntelliJ来编辑(AS也可以),首先新建一个Groovy工程:


    定义项目的GroupId和ArtifactId:


    3.png

    build.gradle

    apply plugin:CustomPlugin
    class CustomPlugin implements Plugin<Project> {
        @Override
        void apply(Project project) {
            project.task('CustomPluginTask') {
                doLast {
                    println "自定义插件"
                }
            }
        }
    }
    

    在build.gradle中自定义了一个插件CustomPlugin,在apply方法中创建一个名称为CustomPluginTask的任务。在IntelliJ的Terminal中输入gradlew.bat CustomPluginTask来执行CustomPluginTask任务。


    1.2 自定义插件扩展

    再举一个简单的插件拓展例子,通过插件拓展来配置CustomPluginTask的输出字符串,如下所示。
    build.gradle

    class CustomPluginPluginExtension {
        String message = 'from CustomPlugin'
    }
    class CustomPlugin implements Plugin<Project> {
        @Override
        void apply(Project project) {
            def extension = project.extensions.create('custom', CustomPluginPluginExtension)//1
            project.task('CustomPluginTask') {
                doLast {
                    println extension.message
                }
            }
        }
    }
    apply plugin: CustomPlugin
    custom.message = "自定义插件拓展"//2
    

    CustomPluginPluginExtension类中定义了message变量,CustomPluginPluginExtension是一个Groovy Bean(类似于JavaBean)。注释1处用于添加拓展插件CustomPluginPluginExtension到插件列表中,名称为custom。注释2处设置CustomPluginPluginExtension的message值。
    Terminal中输入gradlew.bat CustomPluginTask来执行CustomPluginTask任务。


    2.buildSrc工程项目

    除了在build.gradle中编写的自定义插件,还可以将插件的源代码放在rootProjectDir/buildSrc/src/main/groovy目录中,Gradle会自动识别来完成编译和测试。
    在第一节的工程根目录下建立/buildSrc/src/main/groovy目录,如下图所示。


    在groovy目录中创建一个groovy文件,比如我的是CustomPlugin.groovy:
    buildSrc/src/main/groovy/CustomPlugin.groovy
    import org.gradle.api.Plugin;
    import org.gradle.api.Project;
    class CustomPlugin implements Plugin<Project> {
        @Override
        void apply(Project project) {
            project.task('CustomPluginTask') {
                doLast {
                    println "自定义插件"
                }
            }
        }
    }
    

    修改build.gradle为如下的内容:
    build.gradle

    apply plugin: CustomPlugin
    

    Terminal中输入gradlew.bat CustomPluginTask来执行CustomPluginTask任务,会打印出我们想要的结果。

    3.独立项目

    无论是在build.gradle中编写自定义插件,还是buildSrc项目中编写自定义插件,都只能在自己的项目中进行使用。如果想要分享给其他人或者自己用,可以在一个独立的项目中编写插件,这个项目会生成一个包含插件类的JAR文件,有了JAR文件就很容易进行分享了。

    3.1 自定义插件

    为了和前两种方式进行区分,用IntelliJ新建一个Groovy工程,我的工程名为CustomPluginShare,后面会用到。
    配置build.gradle

    apply plugin: 'groovy'
    
    dependencies {
        compile gradleApi()
        compile localGroovy()
    }
    

    应用Groovy插件,并将Gradle API添加为编译时依赖项,build工程,会在External Libraries中生成三个jar文件:


    这样我们可以在非buildSrc工程项目中使用groovy语法和Gradle的api了。
    创建自定义插件
    在src/main/groovy/ 目录中创建一个包,我的是com.example.plugins,在com.example.plugins创建一个groovy文件:
    src/main/groovy/com/example/plugins/CustomPlugin.groovy

    package com.example.plugins
    import org.gradle.api.Plugin
    import org.gradle.api.Project
    class CustomPlugin implements Plugin<Project> {
        @Override
        void apply(Project project) {
            project.task('CustomPluginTask') {
                doLast {
                    println "自定义插件"
                }
            }
        }
    }
    

    配置properties文件
    在buildSrc工程项目中,Gradle可以自动的去识别插件,独立项目中的插件是如何被Gradle识别的呢?答案是需要在生成的JAR文件中提供一个属性文件,这个属性文件名要与插件id相匹配。在resources中创建src/main/resources/META-INF/gradle-plugins/com.example.plugins.customplugin.properties,这个属性文件的名称实际就是插件的id。将properties文件的内容改为:

    src/main/resources/META-INF/gradle-plugins/com.example.plugins.properties

    implementation-class=com.example.plugins.CustomPlugin
    

    implementation-class属性为自定义插件的名称。
    上传插件
    这里为了方便举例直接将插件上传到本地,如果想要发布到Maven、ivy等仓库,见下面的文档:
    https://docs.gradle.org/4.4/userguide/publishing_ivy.html
    https://docs.gradle.org/4.4/userguide/publishing_maven.html
    想要发布到Gradle插件门户上,见下面的文档:
    https://docs.gradle.org/4.4/userguide/plugins.html#sec:plugins_block
    在build.gradle文件中添加如下内容:

    apply plugin: 'maven'
    group = 'com.example.plugins'
    version = '1.0.0'
    uploadArchives {
        repositories {
            mavenDeployer {
                repository(url: uri('../repo'))
            }
        }
    }
    

    这段代码会将生成的插件上传到项目的平级目录repo下。定义了group和version的名称,这些值会在其他项目依赖该插件时用到。我们Build后会在Gradle窗口中看到uploadArchives,如下图所示。



    点击uploadArchives会在本地生成插件相关的文件,比如我的目录和文件如下图所示。



    图中的CustomPluginShare-1.0.0.rar就是我们需要的插件jar包。

    3.2 在另一个项目中使用插件

    新建一个Groovy项目,我取名为Projet,build.gradle的代码如下:

    apply plugin: 'com.example.plugins.customplugin'
    
    buildscript {
        repositories {
            maven {
                url uri('../repo')
            }
        }
        dependencies {
            classpath 'com.example.plugins:CustomPluginShare:1.0.0'
        }
    }
    

    其中com.example.plugins是group,CustomPluginShare是自定义插件的名称,1.0.0是版本号,也可以这么写:

       dependencies {
            classpath group: 'com.example.plugins', name: 'CustomPluginShare',
                    version: '1.0.0'
        }
    

    Terminal中输入gradlew.bat CustomPluginTask来执行CustomPluginTask任务,大功告成。
    如果我们将自定义插件发布到Gradle插件门户上,就可以使用插件DSL了:
    build.gradle

    plugins {
        id 'com.example.plugins.customplugin' version '1.0.0'
    }
    

    虽然讲解独立项目的例子超级简单,但我还是将代码上传到GitHub上了,也许会有同学用的上:
    https://github.com/henrymorgen/CustomPlugin

    总结

    本篇文章介绍了自定义Gradle插件的3种方式,旨在以最简单的例子来让大家快速掌握,如果还想了解复杂的自定义插件可以去查看一些开源的Gradle插件,或者在工作中去实践。本篇文章也为学习Android Gradle插件打下了伏笔。


    分享大前端、Java、跨平台等技术,关注职业发展和行业动态。


    相关文章

      网友评论

        本文标题:Gradle核心思想(六)自定义Gradle插件的三种方式

        本文链接:https://www.haomeiwen.com/subject/cvaciqtx.html