这篇文章讲解如何自定义一个Gradle插件,实现功能是将application module中的dependencies{…}配置部分交给插件,将插件上传到maven仓库,通过云端来配置项目的依赖。
新建一个Android Project,名为GradlePluginDemo,并新增library名为pluginlib,这个library就作为“gradle plugin library”。
因为目前Android Studio还不支持新建gradle plugin module,所以新建一个普通的Android Library Module,再手动修改成gradle plugin module。
如何修改呢?
1、将src/main下的目录全删除
2、将build.gradle文件内容删除,并添加一行 apply plugin: 'groovy'
3、在src/main下新建两个目录:groovy
和resources/META-INF/gradle-plugins
groovy下放的是源代码,resources下是资源文件。
这样就完成了library改造。
在pluginlib中的build.gradle中添加依赖:
dependencies{
// gradle sdk
implementation gradleApi()
// groovy sdk
implementation localGroovy()
}
在src/main/groovy下新建包名(比如com.devnn.plugin),并新建插件类(比如PluginImpl.groovy)。
插件类必须实现Plugin接口,并重写apply方法:
package com.devnn.plugin
import org.gradle.api.Plugin
import org.gradle.api.Project
public class PluginImpl implements Plugin<Project>{
void apply(Project project){
//这里写自定义插件实现逻辑
}
}
apply方法是在apply plugin: '插件名称'
这行脚本执行的时候调用。
在这里,我们要实现的功能是将app module的依赖部分写在插件里,并将插件上传到maven私有库。
插件实现代码如下:
package com.devnn.plugin
import org.gradle.api.Plugin
import org.gradle.api.Project
public class PluginImpl implements Plugin<Project>{
void apply(Project project){
System.out.println("========================")
System.out.println("apply MyPlugin succeed!")
System.out.println("========================")
project.repositories{
maven{
//添加maven库地址
url 'http://localhost:8081/nexus3/repository/maven-public/'
}
}
//定义project的依赖部分
project.dependencies {
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.devnn.lib:lib1:1.1.5'
}
}
}
前三行是一个日志打印。这里有一个自定义的名为lib1的library加进了依赖。
在使用插件的module中,需要在build.gradle中添加
apply plugin: '插件名称'
因此需要给我们的自定义插件定义一个名称。
如何定义插件名称?
在src/main/resources/META-INF/gradle-plugins
下面新建一个properties文件,文件名称就是我们的插件名称,比如MyPlugin.properties
,插件名称就是"MyPlugin"。
文件内容中指定插件类的路径:
implementation-class=com.devnn.plugin.PluginImpl
至此,自定义插件的过程就完了。
将插件打包出来就需要写上传代码。可以上传到本地仓库,或者远程仓库。两种方式只是上传地址不同。最终形成的插件包是一个jar文件。
上传插件跟上传aar/jar的是一样的,在我的另一篇文章中已经有详细讲解:
将aar及其依赖aar上传至maven私有仓库
这里就不再细述。
首先在pluginlib的build.gradle文件中应用maven上传插件:
apply plugin: 'maven'
添加上传脚本:
def NEXUS_REPOSITORY_URL="http://localhost:8081/nexus3/repository/maven-releases/"
def NEXUS_USERNAME="admin"
def NEXUS_PASSWORD="123456"
uploadArchives {
repositories {
mavenDeployer {
pom.groupId = 'com.devnn.plugin'
pom.artifactId = 'myplugin'
pom.version = '1.0.0'
repository(url: NEXUS_REPOSITORY_URL) {
authentication(userName: NEXUS_USERNAME, password: NEXUS_PASSWORD)
}
}
}
}
完整的build.gradle文件内容:
apply plugin: 'groovy'
apply plugin: 'maven'
dependencies{
// gradle sdk
implementation gradleApi()
// groovy sdk
implementation localGroovy()
}
def NEXUS_REPOSITORY_URL="http://localhost:8081/nexus3/repository/maven-releases/"
def NEXUS_USERNAME="admin"
def NEXUS_PASSWORD="123456"
uploadArchives {
repositories {
mavenDeployer {
pom.groupId = 'com.devnn.plugin'
pom.artifactId = 'myplugin'
pom.version = '1.0.0'
repository(url: NEXUS_REPOSITORY_URL) {
authentication(userName: NEXUS_USERNAME, password: NEXUS_PASSWORD)
}
}
}
}
如果是上传到本地仓库,只需要将repository改成:
repository(url: uri(’…/plugins’)) //上传到上级plugins目录
在终端中执行上传命令:
./gradlew pluginlib:uploadArchives
执行上传命令后,自定义插件类会报红,这是AS自身的问题,不要在意,删除build目录就好了。
到maven私有库上看一下刚刚上传的插件:
可以看到已经上传成功了。
上面讲解了通过Gradle的uploadArchives命令上传插件到Maven仓库,这个操作可以通过Jenkins帮助我们自动完成。当更新了插件代码后,可以自动触发jenkins打包并上传插件。客户端应用的依赖部分代码(dependencies{…})就完成了云端化。
在工程根目录的build.gradle文件的buildscipt添加插件所在仓库地址,并且添加插件依赖:
buildscript {
repositories {
google()
jcenter()
maven{
url 'http://localhost:8081/nexus3/repository/maven-public/'
}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.2'
classpath 'com.devnn.plugin:myplugin:1.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
如果是插件是在本地文件库,库的地址那一行改成 url uri(‘plugins’)
在application moudle(app)中应用插件:
apply plugin: 'MyPlugin'
这样就会自动引入了这三个库:
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.devnn.lib:lib1:1.1.5'
application module下面没有配置自己dependencies,全部通过插件来实现。
整个过程的Demo工程源码地址:
https://github.com/devnns/GradlePluginDemo.git