gradle是一种构建工具,用来控制代码的编译、构建、打包等过程,自定义Gradle在Android中应用是很广泛的,比如在gradle构建过程中使用字节码技术、默认的Android项目中应用了很多插件,比如java、groovy、com.android.application等,了解Gradle插件有助于更好的理解生成APK的过程。
自定义插件三种方式:
- build script:在
build.gradle
脚本中直接编写,只能在本文件内使用; - buildSrc项目:新建一个名为
buildSrc
的Module,只能在本项目中使用; - 独立的项目:在独立的项目中编写插件,发布到本地或者远程maven仓库供其他项目使用。
1. 基础知识
本文基于Android进行讲解,实际上任何一个gradle project都可以,阅读本文你可以需要具备基本的gradle知识、groovy语法,可以参考我的两外两篇文章。
建议有gradle基础的和英文水平较高的直接阅读Gradle官方文档:Gradle custom_plugins
2. 方式一:build script
直接在脚本文件中编写插件,线上项目一般不这样做。
2.1 创建Project编辑project下的buid.gradle文件
创建一个project,直接在app module下的build.gradle脚本文件编写插件。
示例:
编辑build.gradle文件,新增插件GreetingPlugin,内容如下:
1 | class GreetingPlugin implements Plugin<Project> { |
不推荐这样做:
- 维护成本高:造成build.gradle文件过于臃肿
- 无法复用:plugin只能在app module中使用,不能给其他module和project使用。
2.2 build.gradle优化的方式
通过apply from: '../script/xxx.gradle'
应用xxx.gradle
脚本中编写的插件。
创建script/test.gralde
文件并添加以上脚本内容。如图:
在app module
使用,添加apply from: '../script/test.gradle'
即可应用test.gralde
脚本。
3.方式二:buildSrc
一般用于本地调试使用
3.1 搭建buildSrc module
在工程中新建buildSrc目录,名称一定不能写错,在buildSrc目录下建立如下目录和文件:
1 | src/ |
编辑build.gradle文件,添加如下内容:
1 | plugins { |
项目结构如下:
点击sync
或者buid project
(这一步必须),会生成build目录,groovy目录也会变成源文件目录,之后就可以创建包和源代码。
3.2 写插件
在groovy目录下新建包(new->package):com.learn.plugin。
新建MyPlugin.groovy文件,必须以.groovy为后缀。添加如下内容:
1 | package com.learn.plugin |
到这里插件已经写好了,在其他地方使用即可。
3.3 其他module中使用buildSrc中的插件
在app module下的build.gradle中应用插件:
1 | apply plugin: com.learn.plugin.MyPlugin |
在终端输入如下命令验证:
1 | ./gradlew assemble |
或者直接Run也可以。
输出如下内容表示成功:
1 | > Configure project :app |
3.4 总结
- module名称必须是buildSrc
- 一般本地调试使用,项目中使用都是远程jar包形式,即第三种方式
4.方式三:独立项目
这种方式是项目中常用的,最后生成的是jar包,可以发布在本地或者远程仓库(jcenter、maven),方便其他项目使用。
4.1 新建写插件的module
新建一个module(新建一个工程也可以,因为最后生成和使用都是jar包的形式),module名称随意,只保留build.gradle文件和src/main目录,其余文件全部删掉。
修改build.gradle文件内容,如下:
1 | apply plugin: 'groovy' //必须,groovy写插件必须 |
相比buildSrc方案,增加了Maven的支持和uploadArchives这样一个Task,这个Task的作用是为了将插件打包上传到本地maven仓库。
这里使用的本地地址:/Users/username(你电脑的名称)/.hhrepo
4.2 写插件
同方式二,这里直接给出结果:
4.3 发布
在终端中执行./gradlew uploadArchives
指令,或者展开Android Studio右侧的Gradle,找到对应module->uploadArchivesTask
,就可以将插件部署到相应的目录下。
验证结果:
4.4 其他项目使用
修改project(根目录)下的build.gradle文件内容,如下:
1 | ... |
在app中使用,修改app下的build.gradle,添加如下内容:
1 | apply plugin: com.ccc.plugin.PluginTest//插件类的全限定名 |
在终端输入如下命令验证:
1 | ./gradlew assemble |
或者直接Run也可以,看到相关提示则成功。
4.5 总结
- 项目中一般使用这种方式,方便项目插件化
5. 拓展
有人可能见过通过META-INF中properties配置插件,没错,这种配置是比较推荐的,对于提供独立自定义插件的JAR,强烈推荐这种做。
一般插件很少直接使用插件类的全限定名调用,比如:
1 | //不推荐 |
基本上都是通过插件名或者叫插件id调用,比如官方的java、groovy、com.android.application等,都是通过如下配置使用:
1 | //推荐 |
这样做的原因:可能是不想插件类暴露出来吧,可以自定义别名。(以后知道原因了再更新)
配置别名步骤:
在main目录下新建resources/META-INF/gradle-plugins
目录,名称不能随意填写。
在gradle-plugins
下新建name(插件名).properties
文件,这个name就是后面要使用的,如图:
其他module使用这个插件:
1 | apply plugin:'hhhhh' |
执行./gradlew assemble
验证
6. 总结
开发gradle插件掌握方式三就行了,关键是项目里面有相关的内容能看懂就行了,比如字节码插桩、编译优化等都会涉及AGP的内容。再此安利:Gradle userguide