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来完成不同的逻辑即可。