Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱
MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

AS 自定义 Gradle plugin 插件 案例 MD


目录

AS 中自定义 Gradle plugin

参考1

参考2

结合 AndroidStudio,自定义Gradle plugin可以完成很多功能,比如:添加编译依赖、进行Aspecj编译、自动生成混淆配置。

项目中引入自定义 Gradle plugin 一般有三种方法:

  • 直接写在 build.gradle 中,这种方式的缺点是无法复用插件代码,在其他项目中还得复制一遍代码
  • plugin 源码放到 rootProjectDir/buildSrc/src/main/groovy 目录下(没用过)
  • plugin 打包后发布到 maven 仓库, 然后项目通过依赖的形式引入

下面介绍的是第 3 种方式

编写插件

1、创建插件 module

新建一个Android工程,在这个工程里面新建一个Android Library,先起名叫 cooker-plugin 吧,我们将会用这个 library 写 Gradle plugin

2、建立 plugin 的目录结构

把这个 cooker-plugin 中除了build.gradle文件外的默认文件都删除,然后按照下面新建文件:

  • 在新建的module中新建文件夹src,接着在src文件目录下新建main文件夹,在main目录下新建groovy目录,这时候groovy文件夹会被Android识别为groovy源码目录。
  • 除了在main目录下新建groovy目录外,你还要在main目录下新建resources目录,同理resources目录会被自动识别为资源文件夹。
  • 在groovy目录下新建项目包名,就像Java包名那样。
  • 在resources目录下新建文件夹META-INF,META-INF文件夹下新建gradle-plugins文件夹。

这样,就完成了gradle 插件的项目的整体搭建,之后就是小细节了。目前,项目的结构是这样的:

3、声明 plugin 信息

src/main/resources/META-INF/gradle-plugins 里声明 plugin 信息,比如新建cooker-plugin.properties文件(文件名 cooker-plugin 是插件名称),在其中指定插件的实现类的全路径类名:

implementation-class=com.helen.plugin.CookerPlugin

4、配置 build.gradle

在 build.gradle 中声明用 groovy 开发

apply plugin: 'groovy'

dependencies {
compile gradleApi()
compile localGroovy()
} repositories {
mavenCentral()
}

5、编写插件逻辑

插件代码放在 src/main/groovy 下,实现 plugin,其实就是实现 Plugin<Project> 接口

package com.helen.plugin

import org.gradle.api.Plugin
import org.gradle.api.Project class CookerPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
println "这里实现plugin的逻辑!"
project.task('cooker-test-task').doLast { variant ->
println "自定义任务-doLast"
}.doFirst { variant ->
println "自定义任务-doFirst"
}
}
}

6、生成 plugin 插件

在 cooker-plugin 项目中,build 一下

任务完成以后,就能在build/libs下生成对应的 plugin 插件了

现在这个插件就能使用了,可以发布在本地仓库或者 Maven 仓库

传递参数

接下来我们介绍如何获得自定义的参数

1、新建 PluginExtension.groovy,用于定义我们可以支持的参数:

class PluginExtension {
def param1 = "param1 defaut"
def param2 = "param2 defaut"
def param3 = "param3 defaut"
}

我们希望能传入嵌套的参数,所以再新建一个 PluginNestExtension.groovy:

class PluginNestExtension {
def nestParam1 = "nestParam1 defaut"
def nestParam2 = "nestParam2 defaut"
def nestParam3 = "nestParam3 defaut"
}

2、新建一个 CustomTask.groovy,继承 DefaultTask 类,使用 @TaskAction 注解标注实现的方法:

class CustomTask extends DefaultTask {

    @TaskAction
void output() {
println "param1 is ${project.pluginExt.param1}"
println "param2 is ${project.pluginExt.param2}"
println "param3 is ${project.pluginExt.param3}"
println "nestparam1 is ${project.pluginExt.nestExt.nestParam1}"
println "nestparam2 is ${project.pluginExt.nestExt.nestParam2}"
println "nestparam3 is ${project.pluginExt.nestExt.nestParam3}"
}
}

这里我们只是做了拿到了参数,然后做最简单的输出操作,使用 ${project.pluginExt.param1}${project.pluginExt.nestExt.nestParam1} 等拿到使用者设置的值。

3、在 apply 方法中建立映射关系:

project.extensions.create('pluginExt', PluginExtension)
project.pluginExt.extensions.create('nestExt', PluginNestExtension)
project.task('customTask', type: CustomTask)

4、定义外部参数,这里我们定义了param1,param2,nestParam1,nestParam2,而param3和nestParam3保持默认。

pluginExt {
param1 = 'app param1'
param2 = 'app param2'
nestExt {
nestParam1 = 'app nestParam1'
nestParam2 = 'app nestParam2'
}
}

这样之后,在执行customTask时就会输出使用者对自定义的参数设置的值

发布插件到仓库

发布到仓库的方式有很多,下面只介绍利用 mavenDeployer 插件发布在本地仓库

1、引入 mavenDeplayer 插件

修改 cooker-plugin 的 build.gradle,添加如下内容:

apply plugin: 'maven'//添加maven plugin,用于发布我们的jar
uploadArchives {
repositories {
mavenDeployer {
pom.groupId = 'com.helen.plugin'
pom.artifactId = 'cooker-plugin'
pom.version = 1.0
repository(url: uri('../release')) //文件发布目录(相对当前 build.gradle 的路径)
}
}
}

2、用 uploadArchices 发布

运行 uploadArchives 就能在设置的仓库路径中生成 cooker-plugin 了

使用插件

1、在 build.gradle 中引入 cooker-plugin

buildscript {
repositories {
jcenter()
maven {
url uri('release') //cooker-plugin 所在的仓库,这里是本地目录(相对当前 build.gradle 的路径)
}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'com.helen.plugin:cooker-plugin:1.0' //引入cooker-plugin
}
}
apply plugin: 'cooker-plugin'

2、我们编译 App 的时候 cooker-plugin 就会介入了

每次 clean/build 时, 在 Gradle Console 可以看到我们的 log

这里实现plugin的逻辑!

3、使用 cooker-plugin 中定义的 task

前面demo中,我们新建了两个task: cooker-test-taskcustomTask, 我们可以通过两种方式运行这两个task,一种方式是双击 app > other 分类下的 task 名,一种是通过 gradlew 命令

cooker-test-task 打印的日志:

Executing tasks: [cooker-test-task]

这里实现plugin的逻辑!
:app:cooker-test-task
自定义任务-doFirst
自定义任务-doLast

customTask 打印的日志:

Executing tasks: [customTask]

这里实现plugin的逻辑!
:app:customTask
param1 is app param1
param2 is app param2
param3 is param3 defaut
nestparam1 is app nestParam1
nestparam2 is app nestParam2
nestparam3 is nestParam3 defaut

到此为止, 自定义Gradle plugin的基本过程就介绍完了。

2019-2-11

AS 自定义 Gradle plugin 插件 案例 MD的更多相关文章

  1. java基础---->自定义gradle的插件

    这里面简单的介绍一下gradle插件的编写. 自定义gradle插件 我们编写的gradle脚本一般是放在build.gradle文件中.所以首先创建一下build.gradle文件,下面的例子都是在 ...

  2. 自定义gradle plugin

    最近开始接触gradle 正好有个需求apidoc

  3. 通过Gradle Plugin实现Git Hooks检测机制

    背景 项目组多人协作进行项目开发时,经常遇到如下情况:如Git Commit信息混乱,又如提交者信息用了自己非公司的私人邮箱等等.因此,有必要在Git操作过程中的适当时间点上,进行必要的如统一规范.安 ...

  4. AS Gradle构建工具与Android plugin插件【大全】

    Android plugin version 与 gradle version 的关系 Gradle是一种构建工具,它通过编写一个名为build.gradle的脚本文件对项目进行设置,再根据这个脚本对 ...

  5. Gradle的构建过程都不会?带你全面了解Android如何自定义Gradle 插件

    目前 Android 工程的默认构建工具为 Gradle,我们在构建 APK 的时候往往会执行 ./gradlew assembleDebug 这样的命令.. 那么这个命令到底代表着什么含义呢?命令的 ...

  6. 手把手带你自定义 Gradle 插件 —— Gradle 系列(2)

    请点赞加关注,你的支持对我非常重要,满足下我的虚荣心. Hi,我是小彭.本文已收录到 GitHub · Android-NoteBook 中.这里有 Android 进阶成长知识体系,有志同道合的朋友 ...

  7. Gradle Groovy 基础语法 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  8. 服务 AIDL 定向tag IPC Parcelable 案例 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  9. gradle ssh 插件

    org.hidetake.ssh Gradle SSH Plugin is a Gradle plugin which provides remote command execution and fi ...

随机推荐

  1. CNN中各种各样的卷积

    https://zhuanlan.zhihu.com/p/29367273 https://zhuanlan.zhihu.com/p/28749411 以及1*1卷积核:https://www.zhi ...

  2. django----用户认证(auth模块)

    用法 from django.contrib import auth user = authenticate(username='someone',password='somepassword') l ...

  3. cf792b循环链表

    头尾链接一下就好, /* 1 2 3 4 5 6 7:4 5 6 7 1 2 3:2 3 5 6 7 1:5 6 7 1 3:6 7 1 3:1 3 7 */ #include<bits/std ...

  4. python 全栈开发,Day38(在python程序中的进程操作,multiprocess.Process模块)

    昨日内容回顾 操作系统纸带打孔计算机批处理 —— 磁带 联机 脱机多道操作系统 —— 极大的提高了CPU的利用率 在计算机中 可以有超过一个进程 进程遇到IO的时候 切换给另外的进程使用CPU 数据隔 ...

  5. JS高级 - 面向对象4(json方式面向对象)

    把方法包在一个Json里 var p1 = { name: "唐三", sex: "男", dreamdu: { URL: "www.dreamdu. ...

  6. SpringAOP学习第一天 @Pointcut注解

    自从上班之后,就很少再看AOP相关的内容,几年时间里虽然也有一两次完整看过,一直没有机会用到,都忘记了.今天重温一下 TestNG测试类 package com.test.spring.aop.min ...

  7. hihocoder 1343 : Stable Members【拓扑排序】

    hihocoder #1343:题目 解释:一个学习小组,一共有N个学员,一个主管.每个学员都有自己的导师(一个或者多个),导师可以是其他学员也可以是主管.每周学员都要把自己的学习报告和收到的报告提交 ...

  8. [SDOI2012]拯救小云公主

    题解: 是一个不错的题目 首先我们可以考虑二分答案 然后变成判定性问题 对于每个画一个圆 当其会被阻断时就是答案 阻断有四种情况 左下 上下 左右 右上 但是这样是n^2a(n)*logn的 考虑直接 ...

  9. day8--socket回顾

    后面学习了线程.协成和异步,它们的框架都是基于socket的协议,基本原理都是一样的,现在把这几个模块重温一下,尽量掌握这些知识更全面一些. 动态导入模块,知道知道模块名,可以像反射一样,使用字符串来 ...

  10. Codeforces Round #228 (Div. 1)

    今天学长给我们挂了一套Div.1的题,难受,好难啊. Problem A: 题目大意:给你n个数字,让你叠成n堆,每个数字上面的数的个数不能超过这个数,如 3 上面最多放三个数字 问你,最少能放几堆. ...