Gradle之自定义插件
前面两篇了解了Gradle的基础知识,最终目的就是为了自己能写出Gradle插件来解决现实项目中的问题。现在Gradle自定义插件用的越来越广泛,插件化,热修复,性能优化,指标检测,多渠道打包等等都会用到Gradle插件。
自定义Gradle插件的方式有三种,代码都差不多,都是必须实现 Plugin<T> 这个接口,然后实现接口中的 apply 方法。只不过写的地方不一样。
在AndroidStido中创建一个新项目,然后直接在app目录下的build.gradle文件中写插件
class MyPlugin implements Plugin<Project>{
@Override
void apply(Project target) {
println('MyPlugin执行了')
target.task("mytask"){
doLast {
println('MyPlugin中的task执行了')
}
}
}
}
定义一个MyPlugin插件实现Plugin接口。然后在apply方法中自定义一个task。一个简单的插件就完成了。
然后在当前build.gradle文件中引入插件
apply plugin: MyPlugin
OK完成,然后在控制台执行一下我们自己的task,window下命令: gradlew mytask 输出如下,Mac在gradlew前面加个./
> Configure project :app MyPlugin执行了 > Task :app:mytask MyPlugin中的task执行了
使用这种方式可以很快的创建一个插件,不过缺点也很明显:
buildSrc是Gradle中的默认插件目录,编译的时候Gradle会自动识别这个目录,将其内的代码编译成插件。
可以先创建一个java的module,然后修改一个build.gradle文件为下面
apply plugin: 'groovy'
只写上面的一句话就行。因为需要写一个groovy项目,所以把main文件夹下的原来的java入口文件夹直接改成groovy,这种方式比较方便。
或者重新建一个groovy文件夹,然后把这个文件夹设置为项目的入口文件设置方式如下
sourceSets {
main {
groovy {
srcDir 'src/main/groovy'
}
}
}
然后开始在groovy文件夹下写插件代码 com.hsm.buildsrc.MyPlugin
class MyPlugin implements Plugin<Project> {
@Override
void apply(Project target) {
println('buildSrc中MyPlugin执行了')
target.task("mytask"){
doLast {
println('buildSrc中MyPlugin中的task执行了')
}
}
}
}
写完插件,怎么让gradle知道哪个是插件呢?
com.hsm.buildsrc 。在properties文件中指明我们自定义的插件的类 implementation-class=com.hsm.buildsrc.MyPlugin
然后去app中的build.gradle文件中引入插件
apply plugin: 'com.hsm.buildsrc'
最后控制台输入命令验证插件 gradlew mytask
> Configure project :app buildSrc中MyPlugin执行了 > Task :app:mytask buildSrc中MyPlugin中的task执行了
使用这种方式写的插件,整个工程中的所有module都可以引用到,而且插件代码在自己的文件夹中,也方便维护。
第二种方式写的插件只能在当前工程中使用,有时候我们需要插件能多个工程都能使用,比如我们的项目中可以使用butterknife的插件,可以使用greenDao的插件。这就需要把我们的插件上传到别的仓库中比如maven。
在项目中新建一个module,这里命名为plugin_module,可以是java module也可以是android Library反正最后都得改嘿嘿。最好建个java的改的少。
修改build.gradle文件为下面
apply plugin: 'groovy'
apply plugin: 'maven'
dependencies {
//gradle sdk
implementation gradleApi()
//groovy sdk
implementation localGroovy()
}
//uploadArchives是将已经自定义好了插件打包到本地Maven库里面去,
//也可以选择打包到远程服务器中。其中, group和version是我们之后配置插件地址时要用到的。
group='com.hsm.plugin_module'
version='1.0'
uploadArchives {
repositories {
mavenDeployer {
//本地的Maven地址:当前工程下
repository(url: uri('./my-plugin'))
//提交到远程服务器:
// repository(url: "http://www.xxx.com/repos") {
// authentication(userName: "admin", password: "admin")
// }
}
}
}
开始编写插件:
class MyPlugin implements Plugin<Project> {
@Override
void apply(Project target) {
println('plugin_module 中MyPlugin执行了')
target.task("mytask"){
doLast {
println('plugin_module中MyPlugin中的task执行了')
}
}
}
}
然后 跟第二步中的步骤一样 创建resources目录和resources下面的各个目录和文件。这里使用的包名是com.hsm.plugin_module
执行gradle命令上传插件jar包到maven仓库 gradlew uploadArchives ,执行完之后jar包就上传到了我们前面定义的./my-plugin下面,内容如下图
最后去工程中使用插件
首先来到主工程的build.gradle文件夹下引入插件的仓库和依赖
buildscript {
repositories {
maven {
//本地仓库地址
url uri('D:/androiddemo/5/GradlePlugin/plugin_module/my-plugin')
}
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.2'
////格式为-->group:module:version
classpath 'com.hsm.plugin_module:plugin_module:1.0'
}
}
然后去app文件夹下的build.gradle文件中引入插件
apply plugin: 'com.hsm.plugin_module'
到这里就OK了,控制台中输入命令验证: gradlew mytask
> Configure project :app plugin_module 中MyPlugin执行了 > Task :app:mytask plugin_module中MyPlugin中的task执行了
我们在集成tinker的时候,会在build.gradle文件中配置tinkerPatch的各种参数比如oldApk ,useSign,buildConfig 等等, 这就是在配置插件中的参数或者属性,而插件的扩展Extension就是用来把这些参数传回插件中。
现在给第三步中的插件添加一个扩展Extension
在插件的module中新建一个实体类MyExtension
package com.hsm.plugin_module
class MyExtension {
int id
String name
}
然后去MyPlugin插件类中添加扩展
class MyPlugin implements Plugin<Project> {
@Override
void apply(Project target) {
println('plugin_module 中MyPlugin执行了')
//1.添加插件扩展到project.extensions集合中
target.extensions.add('myextension',MyExtension)
target.task("mytask"){
doLast {
println('plugin_module中MyPlugin中的task执行了')
//2.获取外界配置的 TestExtension
MyExtension extension = target.myextension
//3.输出插件扩展属性
println ">>>>>> name: ${extension.name} id:${extension.id}"
}
}
}
}
修改完之后重新上传到maven,如果版本号没变,最好先把仓库以前的文件删掉在上传
上传完成之后去项目app目录下的build.gradle中使用
apply plugin: 'com.hsm.plugin_module'
myextension{
id 123
name 'chs'
}
控制台中执行命令验证: gradlew mytask
> Configure project :app plugin_module 中MyPlugin执行了 > Task :app:mytask plugin_module中MyPlugin中的task执行了 >>>>>> name: chs id:123
OK,Gradle创建插件的流程完毕,想要完成更加复杂的功能,只需要在该插件中定义各种各样的task来完成不同的逻辑即可。