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