Android Gradle自定义插件开发
前言
准备对微信Tinker进行学习,而微信Tinker里很重要的一部分是DexDiff算法,并且封装了一个插件来完成这个工作。以前或多或少也接触过Gradle 插件相关的知识,但是并没有实际开发过,所以这篇文章也算学习Tinker之前的一个小小的准备吧。话不多说,下面开始。
环境
电脑系统:
IDE: Android Studio
Gradle 版本:3.3
Java 环境
官方文档 地址
基本知识
Gradle :Gradle是Android的构建工具,很多人理解成一门语言,实际上并不是,Gradle的支持的语言有Groovy,Java,Scala。我个人只会Java,以及一点Groovy。Scala完全不会。
如果想看Groovy请移步 :Groovy
Gradle构建源码解析请移步 :Gralde构建源码解析
Gradle Plugin :我理解成是Gradle的一种扩展,或者是一段还有默认配置的,编辑好的Gradle逻辑。向我们熟悉的 apply plugin: 'com.android.application'
也是Google给我定义好的一套Android App构建插件。通过这套插件规定的流程可以构建出标准的Android Apk出来。
这篇文章可以参考一下:编程角度理解Gradle
好了,我们这篇文章并不是想很多大牛一样,去研究Gradle源码,去分析构建流程,最终目的是为了开发一个自定义的插件,为了后续阅读Tinker源码需要。在阅读源码的基础上再去理解Gradle的思想。
Hello World
So,我们从Hello Gradle Plugin开始
-
新建一个Demo 工程。这个步骤就不贴了。
-
编辑
app/build.gradle
在其末尾加入以下代码apply plugin: GreetingPlugin class GreetingPlugin implements Plugin<Project> { void apply(Project project) { project.task('hello') { doLast { println "Hello from the GreetingPlugin" } } } }
在终端中输入:
./gradlew -q hello
-q表示以安静模式来在执行,所以也可以不需要加
如果命令行出现:Hello from the GreetingPlugin 则表示运行成功。原理我们这就不说了,上面我说的几篇文章里,都有说明。 -
这显然不是我们要的插件,总不能每个过程里都加这么多累赘的代码吧。而我们想要的效果是这样:
apply plugin: 'com.android.application'
-
新建一个Android Library类型的Moudle 名字取名为Gradle_Plugin。删除里面的 test相关包以及Java源码。包括Java源码的包。
-
修改
moudle/build.gradle
。粘贴一下代码:apply plugin: 'groovy' apply plugin: 'maven' dependencies { compile gradleApi() compile localGroovy() } repositories { mavenCentral() }
-
新建Groovy源码包,以及Resources文件夹:这样,整个工程的结构如下:
-
在groovy的路径新建.groovy文件。
源码如下:
package com.touch.xu import org.gradle.api.Plugin import org.gradle.api.Project public class GreetingPlugin implements Plugin<Project> { void apply(Project project) { project.task('hello') { doLast { println "Hello from the GreetingPlugin" } } } }
-
新建.properties文件。路径:
**/resources/META_INF/gradle_plugins/
至于properties的命名,按照自己的含义就来可以了。 -
编辑上一步的properties文件:
implementation-class=com.touch.xu.GreetingPlugin
这个说白了就是声明的作用,是一个Key-Value形式的,既然文件夹叫plugins,也表示可以发布多个插件。记住后面的value,应该是groovy文件夹下面的真实连接,通过 command+click 可以进入相关类的。
-
好了,做完上面的步骤,说明已经开发一款自定义的Gradle 插件出来了。但是这个插件别人要怎么用呢,就想我们在Github上看到那些开源的插件。很简单,他们把插件上传到了Maven仓库中去了,所以我们Apply一下就Ok了,我们这个当然不需要上传到远程Maven中。所以我们需要建立一个本地的Maven,来存放我们的插件。这个过程其实很简单。在moudle/build.gradle中加入以下代码:
group='com.touch.greet.plugin' version='1.0.0' uploadArchives { repositories { mavenDeployer { repository(url: uri('/Users/zfxu/private/study/maven/repo/helloPlugin')) } } }
上面的代码很好理解,仓库地址实际上是我本地的地址。version很好理解,即你插件的版本号,group这个就是上面定义的properties文件的文件名。做好这些以后,点击Android Studio右边的Gradle标签:
-
等待上传。成功后,在上面仓库地址下是可以看到,插件文件的。如下:
说明我们插件上传成功了,至于用法大家都知道。在app/build.gradle
下编辑文件,加入以下代码:buildscript { repositories { maven { url uri('/Users/zfxu/private/study/maven/repo/helloPlugin') } } dependencies { classpath 'com.touch.greet.plugin:gradle_plugin:1.0.0' } } apply plugin: 'com.touch.greet.plugin'
很好理解,上面是引用的maven仓库地址为本地url。依赖不用说,做完这些以后,就可以像大家看的最多的
apply plugin: 'com.android.application'
这样的方式来引用插件了,如果发布的远程Maven中,其他项目也可以用了。PS :
-
记住先把第一步中
app/build.gradle
中的增加的内容删除。 -
做完所有的事情后,运行
./gradlew hello
也会打印那行语句,说明你成功了。 -
如果在发布插件时出现这个问题:
Error:(46, 0) Cause: com/asgradle/plugin/ApkDistPlugin : Unsupported major.minor version 52.0<a href="openFile:/Users/your-user-name/Documents/git/opensource/embrace-android-studio-demo/s5-GradlePlugin/app/build.gradle">Open File</a>
应该是本机的 JDK 版本是1.8,默认将 plugin module 的 groovy 源码编译成了1.8版本的 class 文件,放在 Android 项目中,无法兼容。需要对 plugin module 的 build.gradle 文件添加两个参数:
-
sourceCompatibility = 1.6
targetCompatibility = 1.6
好了,今天就说这么多了。下期我们直接接入微信插件Diff相关插件的源码了,还有很多路要走。加油。