在Android Studio里开发Android APP,用Gradle来做项目的编译构建。有时候会在编译代码的过程中插入一些额外的流程(工具/服务)来完成定制的工作,把这部分流程独立出来,编写成一个插件,这样,可以在项目之间共享通用的程序。下面笔者介绍下如何快速的Get到这门技能。
前期准备
Groovy语言的学习
Gradle插件由Groovy语言编写而成,首先不妨花上一点时间大概了解下Groovy这门语言。推荐首先看看这篇文章IBM developerWorks的精通Groovy,大致过一遍有些了解就好,不用精读,文中的背景介绍,操作实例等都可以略过,重点看下关于无类型,循环范围,集合,映射,闭包等概念,有个初步的认识。这里啰嗦两句关于闭包的神奇之处。
我们先看一段类似于Java的代码:
def acoll = ["Groovy", "Java", "Ruby"]
for(Iterator iter = acoll.iterator(); iter.hasNext();){
println iter.next()
}
再看看更简洁更正确的姿势:
def acoll = ["Groovy", "Java", "Ruby"]
acoll.each{
println it
}
由 {} 包围起来的代码块就是闭包,这样写代码是不是感觉工作效率很高?
闭包中的it变量是一个关键字(Groovy语言内置的默认值),指向被调用的外部集合的每个值,可以用传递给闭包的参数覆盖它(一般不用)。
下面的代码执行同样的操作,但使用自己定义的变量:
def acoll = ["Groovy", "Java", "Ruby"]
acoll.each{ value ->
println value
}
在这个示例中,用value代替了Groovy的默认it。
总结下Groovy的特点
- 代码结束无需分号
- 变量以及函数/方法返回值无需声明类型
- 除非指定,所有成员均为public
- 一个脚本中可以不用定义class
- 闭包
接下来进阶一点的学习,如果你有Java的编程基础,那么看看这篇Groovy和Java的不同之处,上手会快很多。建议精读,因为很多将会是你以后编程的时候遇到的迷惑和坑。
还有一些文章是可以作为炕头书的,在编码的过程中,如果你卡壳了,遇到了一些不知道该如何做的事情,可以立即打开查阅一下
了解Android APP的构建流程
关于这部分详细内容网上已经有很多文章介绍了,这里不再赘述,可以查看本文参考文章里的引用
这里罗列一些在编程的过程中可能需要参考的案头资料,以备不时之需:
贴一张官方提供的编译构建流程图,大家可以大致观摩了解下
编写一个安卓Gradle插件
简述下大概的流程
- 在Android Studio里新建一个项目,然后创建一个Android Library的模块(Android APP,Java Library也可以,创建一个module就好),项目名字自己定义(这里的demo名字叫做mygradleplugin)
- 将这个module的build.gradle的内容修改成为:
apply plugin: 'groovy'
apply plugin: 'maven'
dependencies {
compile gradleApi()
compile localGroovy()
}
repositories {
mavenCentral()
}
group='com.your.name'
version='1.0.0'
uploadArchives {
repositories {
mavenDeployer {
repository(url: uri('../gradle_plugins'))
}
}
}
repository(url: uri(‘../gradle_plugins’))这句话表示生成的插件内容放在主工程的gradle_plugins目录下,方便本地调试,等到插件编写调试完成后,可以通过maven插件发布到公司内部或者外面的公共repo仓库中,注意group和version是maven里表示一个artifact的GVA坐标,也是引用插件需要的
- 将java目录改名为groovy目录,在src/main/groovy/com/your/name/mygradleplugin下新建如下三个groovy文件,分别表示插件入口,外部传递给插件的参数和插件提供的任务
插件执行的入口类,内容如下
package com.your.name.mygradleplugin
import org.gradle.api.Plugin
import org.gradle.api.Project
public class MyGradlePlugin implements Plugin<Project> {
void apply(Project project) {
project.extensions.create('MyGradlePluginParams', MyGradlePluginExtension)
project.task('myGradlePluginTask', type:MyGradlePluginTask)
}
}
外部传递给插件的参数类,内容如下
package com.your.name.mygradleplugin
class MyGradlePluginExtension {
def param = "param defaut"
}
插件提供的任务,内容如下
package com.your.name.mygradleplugin
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction
public class MyGradlePluginTask extends DefaultTask {
MyGradlePluginExtension configuration
ImagesOptTask() {
configuration = project.MyGradlePluginParams
}
@TaskAction
void run() {
println configuration.param
}
}
- 在插件module的src/main/目录下创建目录resources/META-INF/gradle-plugins/,在这个目录下新建文件com.your.name.mygradleplugin.properties,写入如下内容
implementation-class=com.your.name.mygradleplugin.MyGradlePlugin
这句话是为了告诉Gradle,插件的入口类是哪个
一个简单的插件编写完成,功能是提供给Gradle一个叫做myGradlePluginTask的任务,该任务接收传递给它的参数,然后将这个参数内容打印出来
- 执行插件module的uploadArchives任务,会在项目更目录的gradle_plugins下生成插件的内容
- 在主项目中引用插件并测试,在工程根目录的build.gradle文件中加入如下内容
buildscript {
repositories {
maven {
url uri('../gradle_plugins')
}
}
dependencies {
classpath 'com.your.name:mygradleplugin:1.0.0'
}
}
apply plugin: 'com.your.name.mygradleplugin'
MyGradlePluginParams {
param = 'Hello world, my first gradle plugin!'
}
- url uri(‘../gradle_plugins’)表示引用插件的地址
- classpath ‘com.your.name:mygradleplugin:1.0.0’表示插件artifact的GVA坐标,分别由前面定义的group和version以及模块名称决定
- apply plugin: ‘com.your.name.mygradleplugin’由插件resources/META-INF/gradle-plugins/目录下文件com.your.name.mygradleplugin.properties的名字决定
-
MyGradlePluginParams是传递给插件的参数以及内容
- 执行 ./gradlew myGradlePluginTask命令,输出
Hello world, my first gradle plugin!
一个简单的插件就这样编写完成
参考文章
如何使用Android Studio开发Gradle插件
Android自定义Gradle插件
自定义Gradle插件(一)
自定义Gradle插件(二)
构建神器Gradle