Android studio通过Gradle来构建我们的项目。一般情况下,我们只是使用Gradle来配置一些功能,比如,buildTypes,productFlavors等等。
实际上,Gradle提供了很多有用的功能,可以让我们更加方便的管理我们的项目。
这篇,我们介绍下Gradle的Plugin插件。
官方介绍
Gradle的plugin插件,有三种方式:
- 一,Build script 简单说就是在构建脚本中(build.gradle),直接创建编写代码
- 二,buildSrc project 创建一个buildSrc的项目,存放插件的代码
- 三,Standalone project 创建一个单独的项目,生成并发布一个包含插件,任务等内容的jar包。
下面,我们就介绍下三种方式的插件分别怎么创建。
一,Build script
这种方式,就是直接在build.gradle文件中,编写插件代码。
好处:
自动编译,无需执行其他操作。
坏处:
生成的插件,对外部是不可见的,只能在当前的功能下使用。
一般来说,不会使用这种方式。
先看下插件的编写
class GreetingPlugin implements Plugin<Project> {
void apply(Project project) {
project.task('hello') {
doLast {
println 'Hello from the GreetingPlugin'
}
}
}
}
// Apply the plugin
apply plugin: GreetingPlugin
一般来说,我们写的插件,都需要实现Plugin接口。在apply()方法中,写我们要实现的插件代码。
通过 gradlew -q hello调用。
D:\workspace\work_studio\ObjectAnimatorTest>gradlew -q hello
Hello from the GreetingPlugin
D:\workspace\work_studio\ObjectAnimatorTest>
这样,就打印出来结果了。
二,buildSrc project
这种方式,就是创建一个buildSrc的module。
因为,Gradle插件支持groovy,java,kotlin语言,所以,根据我们使用的语言,可以把插件代码分别放到下面几个不同的目录下
rootProjectDir/buildSrc/src/main/groovy
或rootProjectDir/buildSrc/src/main/java
或rootProjectDir/buildSrc/src/main/kotlin
比如,我们想使用java语言来开发插件代码,我们就需要把我们的java代码放到rootProjectDir/buildSrc/src/main/java这个目录下。
这种方式实现的插件好处:
所有的构建脚本都是可见的。
坏处:
只有当前的工程才能使用,其他的工程是不能使用的
下面,我们就开始实现插件代码。
2.1 创建buildSrc的module。
创建一个名字为 buildSrc(名字必须是这个) 的Android module。
把里面的build文件夹,src下面的res文件夹等等,全部删除。
目录结构如下
2.2 通过build.gradle添加依赖
上面说了,我们可以使用groovy,kotlin,java等语言开发。一般来说,使用Java或Kotlin实现的插件是静态类型的,其性能将优于使用Groovy实现的相同插件。这里,我们就使用最熟悉的Java来开发。
给buildSrc的module的build.gradle中添加依赖
//use java library
apply plugin: 'java-library'
//groovy library
//apply plugin: 'groovy'
apply plugin: 'maven'
dependencies{
// gradle sdk
compile gradleApi()
// groovy sdk
compile localGroovy()
}
repositories{
google()
mavenCentral()
}
2.3 创建插件代码
创建插件,需要实现Plugin接口。
这里,我们打印一句话。毕竟,我们只是学习创建Plugin插件的。
package com.liu.loadplugin;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
public class UploadPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
System.out.println("this is my first buildSrc plugin !");
}
}
2.4 创建properties文件,关联插件
我们创建好了插件,接下来,我们需要创建一个properties的文件,把插件的名字跟插件关联起来。
1,创建目录及文件 main/META-INF/gradle-plugins/插件名.properties文件。
比如,我们现在的插件名字是com.liu.loadplugin.properties。
如下图
2,在properties文件添加代码,关联插件
implementation-class=com.liu.loadplugin.UploadPlugin
这个就是关联插件类的全路径(点击是可以跳转到类里面的)。
到这里,我们整个的buildSrc类型的插件就开发完了。
2.5 使用插件
在我们的app的module的build.gradle里面引用插件。
apply plugin: 'com.liu.loadplugin'
这里的名字是跟我们的properties的名字对应的。
重新构建一次,会看到我们在插件里写的那句话,打印出来了。
到这里,我们buildSrc方式开发插件就完成了,下面看下独立的插件开发方式。
三,Standalone project
独立的插件。跟buildSrc的创建方式类似。
但是,它相比与上面的那种,有几个明显的优点:
- 插件的module名字,可以随意
- 这种方式,就是将我们写的一些插件,任务等等打包到一起,生成jar,通过jar包的方式使用。所以, 在其他的项目也是可以使用的 。
下面,我们来创建一个独立的插件。
3.1 创建一个插件的module
跟上面的方式类似,我们创建一个叫alone_plugin(名字随意)的Android module。然后,删除build,res等无用的文件。
结构如下。
3.2 添加依赖(build.gradle)
因为,这种独立插件的方式,最后是通过生成jar包,来共其他工程使用。所以,这里跟上面的方式有点不同。
先看下,build.gradle文件
apply plugin: 'java-library'
apply plugin: 'maven'
dependencies {
compile gradleApi()
compile localGroovy()
}
repositories {
mavenCentral()
}
group = 'com.liu.alone.plugin'
version = '1.0.0'
archivesBaseName = 'java-plugin'
//upload
uploadArchives {
repositories {
mavenDeployer {
repository(url: uri('../repo'))
}
}
}
这里比buildSrc的方式多了下面,这些配置
group = 'com.liu.alone.plugin'
version = '1.0.0'
archivesBaseName = 'java-plugin'
//upload
uploadArchives {
repositories {
mavenDeployer {
repository(url: uri('../repo'))
}
}
}
我们是通过maven的方式,把插件发布到本地的repo目录下。我们知道maven发布需要指定:groupId,artifactId,version的。通过,这三个声明,就可以找到我们的插件。
3.2 创建插件,跟properties文件
这两个步骤跟我们上面的buildSrc创建插件的方式一样。这里就不写了。
目录结构如下图
3.3 maven发布插件
通过Gradle的alone_plugin下面的uploadArchives命令。
把我们的插件,发布到当前工程的repo目录下。
通过上面的命令,就会把插件发布到项目下的repo目录里面。
如下图
3.4 引入插件
在项目的build.gradle引入我们发布的插件
buildscript {
repositories {
google()
jcenter()
maven{
url uri('./repo/')
}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.1'
classpath 'com.liu.alone.plugin:java-plugin:1.0.0'
}
}
通过添加maven仓库。在dependenies里面引用。就把我们的插件引入了。
3.5 使用
在app module的build.gradle里面引用跟buildSrc的方式一样。
apply plugin: 'com.liu.alone.plugin'
最后,重新构建一次。就会打印出,我们插件里写的Log。
到这里,自定义Gradle 插件的三种方式,就介绍完了。
独立的插件,我们这里只是说了,在打包的项目使用。那么,其他的项目应该怎么使用呢。
3.6 其他项目引用插件及优化
3.6.1 其他项目引入插件
独立的插件开发方式的最终目的是让其他的项目也可以使用。那么,别的项目,怎么来引用呢。
这里,我们让其他的项目通过jar包的方式来引用。
首先,在需要引入的项目,创建一个libs文件夹(这个应该是可以随意起的)。
其次,修改项目的build.grandle
buildscript {
repositories {
google()
jcenter()
flatDir{dir 'libs'}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.1'
classpath 'com.liu.alone.plugin:java-plugin:1.0.0'
}
}
这里,我们需要把libs添加进仓库中,然后,依赖这个插件。就完成了在其他项目的使用。
我们再来想一下。这种方式,是需要我们手动把jar包拷贝到需要的项目中的。有什么问题呢?
- 1,手动拷贝,没有那么自动化
- 2,如果这个插件升级了或者修改了呢,我们每次都拷贝?
既然是多个项目用的话。那么,我们可不可以上传到本地仓库。然后,其他的项目也使用本地仓库,来解决上面的问题呢。
3.6.2 优化,上传到本地仓库
这里关于本地仓库配置本地Maven库,就不说明了。
我们首先创建一个本地仓库。让其依赖一个组(android_depend)。
因为我们不只是有一个插件,还有jcenter等等,都可以放到本地仓库中。
然后,修改我们的独立插件alone_plugin的build.gradle。使其发布到本地仓库的android_plugin中,而不再发布到项目的repo目录下。
apply plugin: 'java-library'
apply plugin: 'maven'
dependencies {
compile gradleApi()
compile localGroovy()
compile 'com.android.tools.build:gradle:3.3.1'
implementation("com.squareup.okhttp3:okhttp:3.8.1")
}
repositories {
mavenCentral()
}
//group = 'com.liu.alone.plugin'
//version = '1.0.0'
//archivesBaseName = 'java-plugin'
//
//upload
//uploadArchives {
// repositories {
// mavenDeployer {
// repository(url: uri('../repo'))
// }
// }
//}
//upload to local maven
uploadArchives {
repositories {
mavenDeployer {
repository(url: "http://localhost:8081/artifactory/android_plugin/") {
authentication(userName: "admin", password: "admin")
}
pom.version = "1.0.0"
pom.artifactId = "java-plugin"
pom.groupId = "com.liu.alone.plugin"
}
}
}
这里,我们已经修改其发布的位置了。发布成功后,看下本地仓库。
这里,我们看到已经发布上去了。
然后,我们修改要引用插件的项目下的build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
// google()
// jcenter()
maven{
url 'http://localhost:8081/artifactory/android_depend/'
}
// flatDir{dir 'libs'}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.1'
classpath 'com.liu.alone.plugin:java-plugin:1.0.0'
}
}
allprojects {
repositories {
// google()
// jcenter()
maven{
url 'http://localhost:8081/artifactory/android_depend/'
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
疑惑:这里需要,先发布到本地仓库;然后,把本地仓库添加到组中,这样,组中才有插件的包。
先把本地仓库添加到组中,在发布插件到本地仓库,这样组中是没有这个插件包的(本地仓库有)。
这里,我们看到,我们已经不再使用 libs 目录了,而是换成了本地仓库。
这样的话,如果,独立插件再发布修改或者升级的话,我们也不需要手动拷贝jar包了。直接修改版本就可以了。
到这里,Gradle的插件开发,就全部介绍完了。
自定义插件非常实用,我们完全可以通过自定义插件来一键实现打包,加固,上传,钉钉通知等功能。