自定义Gradle-Plugin 插件详解

自定义Gradle-Plugin 插件

官方文档给出了详细的实现步骤,笔者 将参考官方文档:通过自定义插件实现lint文件输出,本文按照以下三个方面进行讲解:

  • 插件基础介绍
  • 三种插件的打包方式
  • 实例Demo

插件基础介绍

官方介绍:A Gradle plugin packages up reusable pieces of build logic, which can be used across many different projects and builds. Gradle allows you to implement your own plugins, so you can reuse your build logic, and share it with others.

You can implement a Gradle plugin in any language you like, provided the implementation ends up compiled as bytecode. In our examples, we are going to use Groovy as the implementation language. Groovy, Java or Kotlin are all good choices as the language to use to implement a plugin, as the Gradle API has been designed to work well with these languages. In general, a plugin implemented using Java or Kotlin, which are statically typed, will perform better than the same plugin implemented using Groovy.

大体意思:插件打包了可重用的构建逻辑,可以适用不同的项目和构建。

Gradle 提供了很多官方插件,用于支持Java、Groovy等工程的构建和打包。同时也提供了自定义插件机制,让每个人都可以通过插件来实现特定的构建逻辑,并可以把这些逻辑打包起来,分享给其他人。

您可以实现一个Gradle插件用你喜欢任何语言,提供了实现最终编译成字节码。官方例子中,使用Groovy实现语言。Groovy、Java或Kotlin都是不错的选择。深入理解可以参考上一篇文章:Android中Gradle深入理解

Gradle自定义插件三种方式:

There are several places where you can put the source for the plugin.

Build script

You can include the source for the plugin directly in the build script. This has the benefit that the plugin is automatically compiled and included in the classpath of the build script without you having to do anything. However, the plugin is not visible outside the build script, and so you cannot reuse the plugin outside the build script it is defined in.

buildSrc project

You can put the source for the plugin in the rootProjectDir/buildSrc/src/main/groovy directory. Gradle will take care of compiling and testing the plugin and making it available on the classpath of the build script. The plugin is visible to every build script used by the build. However, it is not visible outside the build, and so you cannot reuse the plugin outside the build it is defined in.

See Organizing Gradle Projects for more details about the buildSrc project.

Standalone project

You can create a separate project for your plugin. This project produces and publishes a JAR which you can then use in multiple builds and share with others. Generally, this JAR might include some plugins, or bundle several related task classes into a single library. Or some combination of the two.

大体意思总结为下3点:

1.build.gradle脚本中直接使用。这种方式就是直接在Android Studio app moudle的build.gradle 中进行插件的编写,优点就是不用再上传插件到maven或者其它地方,项目就可以直接使用;缺点也是很明显,就是只能在自己的项目中使用,不能复用,这个不是我们今天要说的。

buildSrc中使用。这种方式需要在项目中新建一个moudle命名为buildSrc,这个目录就用来存放自定义插件。然后在src/main中建立两个目录,一个就是存放代码的groovy目录,一个是存放自定义插件名称的resources目录。这种定义方式也是只能在我们项目中进行使用,不好复用。

3.独立Module中使用。这种方式就是完全独立开发一个Module,可以随便用。

Build Script

把插件写在build.gradle 文件中,一般用于简单的逻辑,只在改build.gradle 文件中可见,这里直接贴出Demo代码:

/**
 * 插件入口类
 */
class TestPlugin implements Plugin<Project> {
    @Override
    void apply(Project project) {
        //do something
    }
}

apply plugin: TestPlugin

buildSrc

Use buildSrc to abstract imperative logic

Complex build logic is usually a good candidate for being encapsulated either as custom task or binary plugin. Custom task and plugin implementations should not live in the build script. It is very convenient to use buildSrc for that purpose as long as the code does not need to be shared among multiple, independent projects.
有兴趣可参考:buildSrc介绍

总得来说:只对该项目中可见,适用于逻辑较为复杂,但又不需要外部可见的插件

独立项目

先来一个整体代码感受:


image
  1. 在Android Studio中新建 Java Library module uploader(moduleName 不重要,根据实际情况定义)
  1. 修改项目文件夹
  • [x] 移除java文件夹,因为在这个项目中用不到java代码
  • [x] 添加Groovy文件夹,主要的代码文件放在这里
  • [x] 添加resource文件夹,存放用于标识gradle插件的meta-data
  1. 修改build.gradle 文件

apply plugin: 'groovy'


dependencies{
    //gradle sdk
    compile gradleApi()
    //groovy sdk
    compile localGroovy()
}
//以上配置比较固定
//以下内容主要用来上传插件
apply plugin: 'maven'
repositories {
    mavenCentral()
}

group = 'com.charles.plugin'
version = '1.0.0'


uploadArchives{
    repositories {
        mavenDeployer{
            repository(url: uri('./../repo'))
        }
    }
}

  1. 创建Groovy脚本

接下来,在groovy目录下,创建一个Groovy类(与Java类似,可以带包名,但Groovy类以.grovvy结尾,所以groovy文件的创建是new->file->custom.groovy)。

//插件是一个类 继承Plugin
class LintPlugin implements Plugin<Project> {

//重载 void apply(Project project)方法,这个方法将会传入使用这个插件的 project 的实例,这是一个重要的 context。
    @Override
    void apply(Project project) {
        /*project.task('lintOutputsTask') {
            doLast {
                println("lint outputs task start...")
            }
        }*/
        project.afterEvaluate {
            project.android.lintOptions.xmlOutput=new File(project.buildDir,"lintResult.xml")
        }
        project.tasks.create('cleanTest',CleanTestTask)
    }
}
  1. 创建resources
    resources目录是标识整个插件的目录,也是后面apply plugin的内容。
image
implementation-class=com.charles.plugin.LintPlugin
  1. 在主项目中使用插件
    在主项目的build.gradle文件中,通过apply指令来加载自定义的插件,脚本如下所示:
apply plugin: 'com.charles.plugin'


buildscript {
    ext.kotlin_version = '1.2.30'
    repositories {
        google()
        jcenter()
        maven {
            url uri('./../repo')
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.3'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath 'com.charles.plugin:lintplugin:1.0.0'

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

对比:
在buildSrc中创建自定义Gradle插件只能在当前项目中使用,因此,对于具有普遍性的插件来说,通常是建立一个独立的Module来创建自定义Gradle插件。

区别在于:

  • 不需要进行model的名称的写死,也就是你可以随意的命名
  • buildSrc会自动的编译和加入到classpath中,这里我们需要手动依赖
  • 需要上传到maven仓库中

参考:

声明:此为原创,转载请联系作者


作者:微信公众号添加公众号-遛狗的程序员 ,或者可以扫描以下二维码关注相关技术文章。

qrcode_for_gh_1ba0785324d6_430.jpg

当然喜爱技术,乐于分享的你也可以可以添加作者微信号:

WXCD.jpeg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,064评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,606评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,011评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,550评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,465评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,919评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,428评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,075评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,208评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,185评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,191评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,914评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,482评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,585评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,825评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,194评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,703评论 2 339

推荐阅读更多精彩内容