android的gradle插件用了不少了,比如说官方的应用构建插件(com.android.application),lib构建插件(com.android.library),还有第三方的比如辅助multidex的DexKnifePlugin。但是怎么自己创建一个gradle插件一直不明白,今天就试一试自己撸一个android gradle插件,毕竟实践出真知。
首先得知道一个gradle插件有需要哪些元素。
我们以android的application插件为例,往往有如下代码,这些代码到底是什么?
//root build.gradle
dependencies {
classpath 'com.android.tools.build:gradle:2.2.3'
}
//app build.gradle
apply plugin: 'com.android.application'
属性 | 值 | 备注 |
---|---|---|
pluginId | com.android.application | 对应一个Plugin类 |
groupId | com.android.tools.build | |
artifactId | gradle | |
version | 2.2.3 |
以上是一个gradle插件必须的属性。然后既然是gradle 插件必须实现Plugin
接口。groupId、artifactId、version指定了一个插件工程,每个插件工程下可以有若干个插件(每个插件一个pluginId)
首先选择科学工具IntelliJ,之前在groovy入门指南1里面已经配置好了groovy和IntelliJ的环境,所以可以直接搞起来。
这里我们配置如下,注意版本号写1.0
4、just next
5、第一次创建gradle工程,他会去下载2个jar,junit:4.11和org.codehaus.groovy:groovy-all:2.3.11,这个下载过程非常慢(好吧,其实是公司网络比较坑),耐心等待。
compile gradleApi()
compile localGroovy()
./gradlew tasks
会显示出来。package com.fish
import org.gradle.api.Plugin
import org.gradle.api.Project
/**
* Created by fish on 17/1/24.
*/
class FirstPlugin implements Plugin<Project> {
void apply(Project project) {
def showTipTask = project.tasks.create("showTips") << {
println('hello I am the first custom plguin')
}
showTipTask.group = "funny"
showTipTask.description = "Hello baby"
}
}
apply plugin: 'maven'
uploadArchives {
repositories {
mavenDeployer {
repository(url: uri('repo'))
}
}
}
方法2是还可以在IJ的terminal窗口执行./gradlew uploadArchives
,推荐使用这种方法,可以看到清楚的日志,特别是失败时日志信息很关键
10、不幸的是,失败了,日志如下
Starting a Gradle Daemon (subsequent builds will be faster)
:compileJava UP-TO-DATE
:compileGroovy FAILED
FAILURE: Build failed with an exception.
可以用./gradlew uploadArchives --stacktrace
看更详细的信息,得到信息如下所示
Caused by: groovy.lang.GroovyRuntimeException: Conflicting module versions. Module [groovy-all is loaded in version 2.4.7 and you are trying to load version 2.3.11
... 10 more
看来是有2个groovy-all,原来IJ依赖了我默认的groovy是2.4.7版本的,然后这里工程又依赖了2.3.11版本的,所以当然会出错了,解决方法是在build.gradle里注释掉compile 'org.codehaus.groovy:groovy-all:2.3.11'
这行代码。
11、我们再执行./gradlew uploadArchives --stacktrace
又会发现如下问题,miss了一个file,想想漏了什么,我们没有指明pluginId
补上它,在main/resources下创建META-INF/gradle-plugins文件夹,在里面建一个properties文件,文件名随便起(包名格式),比如就叫com.apple.propeties,文件里配置类名
implementation-class=com.fish.FirstPlugin
好了run it,此时插件就生成了,生成的插件是主要是jar包和配置文件,结构如下
现在插件已经写好了,怎么使用他呢?
new一个AS工程,叫UseShip好了。然后在根目录的build.gradle加依赖 classpath 'com.netease:ship:1.0'
,在app的build.gradle加apply plugin: 'com.apple'
。现在插件就导进来了,我们在执行apply plugin: 'com.apple'
的时候会调用FirstPlugin的apply方法,在apply方法内我们定义了一个showTipTask,这个task在funny这个group下,来,我们验证下,如下所示 ,果然找到了这个task
此时可以在terminal下执行./gradlew showTips
,得到了正确结果,显示 “hello I am the first custom plguin”
192:UseShip fish$ ./gradlew showTips
To honour the JVM settings for this build a new JVM will be forked. Please consider using the daemon: https://docs.gradle.org/2.14.1/userguide/gradle_daemon.html.
Incremental java compilation is an incubating feature.
:app:showTips
hello I am the first custom plguin
BUILD SUCCESSFUL
Total time: 9.344 secs
我们这里pluginId故意起的跟GroupId、ArtifictId没什么关系,是为了区分清楚,但实际上他们往往是关联的。
http://tools.android.com/build/gradleplugin
http://blog.bugtags.com/2016/03/28/embrace-android-studio-gradle-plugin/
https://docs.gradle.org/current/userguide/custom_plugins.html
Create a Standalone Gradle plugin for Android - a step-by-step guide