本文主要介绍2种自定义Gradle的方法,一种是本地开发使用的,另一种是开发出来给别人使用的,分不同的场景使用。
本地Gradle插件buildSrc
新建Java module创建名为buildSrc,名为buildSrc的插件会自动加入到编译路径,不需要做额外的配置。官网
1、只保留src/main目录及gradle文件,其余文件删除;
2、在src/main路径下新建groovy目录;
3、在src/main路径下新建如下目录:/resources/META-INF/gradle-plugins
修改gradle文件如下:
apply plugin: 'groovy'
dependencies {
implementation localGroovy()
implementation gradleApi()
implementation fileTree(dir: 'libs', include: ['*.jar'])
}
sourceCompatibility = "7"
targetCompatibility = "7"
下面我们在groovy目录下新建包,自定义一个简单的插件:
package com.wzh.gradle
import org.gradle.api.Action
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
public class LocalDemoPlugin implements Plugin {
@Override
void apply(Project project) {
project.task("local",new Action() {
@Override
void execute(Task task) {
println("task "+task.getName()+" is running! ")
}
})
}
}
然后在/resources/META-INF/gradle-plugins目录下新建一个配置文件localgradle.properties,内容如下:
#这里面的class就是我们插件
implementation-class=com.wzh.gradle.LocalDemoPlugin
接下来在app模块使用插件:
apply plugin: 'localgradle'
build以下,我们会看到输出的日志:
task local is running!
我们可以在插件里面进行一些操作,比如可以用TransformAPI对字节码文件进行修改等。
远程Gradle插件
其实这种方式跟上一种方式很类似,只是gradle配置修改一下,具体如下:
1、只保留src/main目录及gradle文件,其余文件删除;
2、在src/main路径下新建groovy目录;
3、在src/main路径下新建如下目录:/resources/META-INF/gradle-plugins
修改gradle文件如下:
apply plugin: 'groovy'
apply plugin: 'maven'
dependencies {
implementation localGroovy() //groovy api
implementation gradleApi() //gradle api
implementation 'com.android.tools.build:gradle:3.3.1' //gradle编译工具
implementation fileTree(dir: 'libs', include: ['*.jar'])
}
group = 'com.wzh.plugin.remote'
version = '1.0.0'
uploadArchives{
repositories{
mavenDeployer{
//会把生成的jar包上传到该目录
repository(url: uri('/Users/wenzhihao/.my_mvn_repo'))
}
}
}
sourceCompatibility = "7"
targetCompatibility = "7"
这里我们会设置插件所属组及插件版本。
groovy目录下自定义一个插件:
public class RemotePlugin extends Transform implements Plugin {
@Override
void apply(Project project) {
//registerTransform
def android = project.extensions.getByType(AppExtension)
android.registerTransform(this)
project.task("remote", new Action() {
@Override
void execute(Task task) {
println("task " + task.getName() + " is running! ")
}
})
}
}
然后在/resources/META-INF/gradle-plugins目录下新建一个配置文件RemoteGradlePlugin.properties,内容如下:
implementation-class=com.wzh.plugin.remote.RemotePlugin
然后我们开始上传插件,运行uploadArchives任务:
然后我们在'/Users/wenzhihao/.my_mvn_repo'目录找到如下生成内容:
这时候我们就可以使用这个插件了。
首先需要在整个项目的gradle文件配置如下:
buildscript {
ext.kotlin_version = '1.3.20'
repositories {
google()
jcenter()
maven {
//引入本地仓库
url uri('/Users/wenzhihao/.my_mvn_repo/')
}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
//引入我们自定义的插件,1.0.0是版本号,
//remoteplugin是插件名称,com.wzh.plugin.remote是组名
classpath "com.wzh.plugin.remote:remoteplugin:1.0.0"
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
在app模块配置gradle,引入插件:
...
apply plugin: 'RemoteGradlePlugin'
....
注意我们使用的时候apply plugin: 'xxx',这里面的xxx正是我们插件properties的名字,如上文插件种的properties文件名为:RemoteGradlePlugin.properties。
编译一下,控制台输出以下信息:
task remote is running!
其实这种方式的插件可以上传到远程maven仓库,这样别人也可以使用到你的插件。
自定义插件用途还是很广泛的,而且功能很强大,比如我们可以用gradle的TransformAPI在class打包成dex文件之前,利用ASM框架去修改class文件,从而实现无侵入式的代码注入等。