自定义 Gradle 插件

Android 中许多优秀的开源框架都会自定义 Gradle 插件,比如,热修复的 Tinker 。

所以,这篇文章记录 Android Studio 中如何自定义 Gradle 插件。


Gradle

Gradle 是个的构建工具,也是Android Studio 默认的构建工具,与传统的 Ant 、maven 相比,Gradle 更加强大。利用 Gradle 这个工具,我们能做很多事情,例如热修复、插件化等等。

当然,这篇文章不会将具体的 Gradle 语法,这篇文章只会记录如何创建一个Gradle 插件。

如果你想彻底理解并应用 Gradle ,推荐看这系列文章 Gradle for Android 。

Gradle 插件是使用 Groovy 语言进行开发的,而 Groovy 是可以兼容 Java 的。Android Studio 除了开发 APP 外,完全可以开发 Gradle 插件。


插件开发

现在来说下,详细的 Gradle 插件开发步骤:

  1. 新建一个项目

  2. 再新建一个 Module,此 Module 用于开发插件,类型选什么都无所谓,后面会大改。

  3. 在 Project 目录视图模式下,清空 build.gradle 文件的内容,删除其余的所有文件。

  4. 然后在 module 中新建多个文件夹 src/main/groovy ,再新建包名文件夹。 在 main 目录下再新建resources 目录,在resources 目录下再新建 META-INF 文件夹,再新建文件夹gradle-plugins,这样就完成了 gradle 插件的目录结构搭建,整个目录结构如下。

  5. 打开 build.gralde 文件,替换全部内容

    apply plugin: 'groovy'
    apply plugin: 'maven'
    
    dependencies {
       compile gradleApi() //gradle sdk
       compile localGroovy() //groovy sdk
    }
    
    repositories {
       jcenter()
    }
  6. 现在,就可以来正式写插件内容了。在刚刚新建的包名下 再次新建一个文件 MyPlugin.groovy ,注意文件类型,一定是 groovy 类型文件,刚开始没注意,直到出了问题,排查时,打开本地文件才发现文件没有后缀名称。

    package com.app.plugin
    
    import org.gradle.api.Plugin
    import org.gradle.api.Project
    
    public class MyPlugin implements Plugin<Project> {
    
     void apply(Project project) {
       def log = project.logger
       log.error "========================";
       log.error "完整的MyPlugin,开始修改Class!";
       log.error "========================";
     }
    }
  7. resources/META-INF/gradle-plugins 目录下新建一个 .properties 文件,注意该文件的命名就是你使用此插件时的名称,这里命名为 com.app.myplugin.properties ,一定要注意后缀名称,那么使用时的名称就是com.app.myplugin,文件里面的内容填写如下:

    implementation-class=com.app.plugin.MyPlugin

    这里是 key = value 的形式,值就是刚刚自定义的 插件( groovy 文件 )的全名,也就是路径加上类名称。


至此,插件也就开发完成了。

这是可以发布出去的完整的插件结构,如果你想开发只针对当前项目的 Gradle 插件,那么可以简化很多步骤,也可以忽略后面的打包发布的繁琐步骤。



简化版 gradle 插件

开发仅用于当前项目的简化版 Gradle 插件的话,绝大部分与前面完整的步骤相同,只是有两点需要注意:

  1. 用于开发插件的 Module 名称必须是 BuildSrc
  2. 无须 resources 目录

整个目录结构简化了许多。

而且 build.gradle 中也去除了 maven 插件 apply plugin: 'maven' ,文件如下:

apply plugin: 'groovy'

dependencies {
  compile gradleApi() //gradle sdk
  compile localGroovy() //groovy sdk
}

repositories {
  jcenter()
}

然后就是编写的插件,MyPlugin.groovy 文件内容如下:

package com.example

import org.gradle.api.Plugin
import org.gradle.api.Project

public class MyPlugin implements Plugin<Project> {

  void apply(Project project) {
    def log = project.logger
    log.error "========================";
    log.error "精简的MyPlugin,开始修改Class!";
    log.error "========================";
  }
}

如果是使用的话,就直接在需要使用的 module 中 build.gradle 添加

apply plugin: com.example.MyPlugin //注意,这里没有单引号,直接填写插件的全名

然后,先 clean 下项目,然后 make project ,就可以在控制台看到效果:



插件的发布

当然,如果你想复用 你的gradle 插件,那就必须把它发布出去。

按发布的地点分类,有两种:

  1. 发布到本地仓库
  2. 发布到远程仓库


本地仓库

如果是发布到本地,则在插件的build.gradle 中添加如下代码 :

uploadArchives {
    repositories.mavenDeployer {
        repository(url: uri('../repo')) //仓库的路径,此处是项目根目录下的 repo 的文件夹
        pom.groupId = 'com.app.plugin'  //groupId ,自行定义,一般是包名
        pom.artifactId = 'gradleplugin' //artifactId ,自行定义
        pom.version = '1.0.0' //version 版本号
    }
}

此处的 groupIdartifactIdversion 这三个参数都是自定义的,后面再引用这个插件时会用到。

maven 本地仓库的目录就是当前项目目录下的 repo 目录,这个时候右侧的 gradle Toolbar 就会在module下多出一个task ,upload-uploadArchives ,在运行这个Task 之前,需要先 clean 项目。运行过后,就会在项目中生成一个 repo 的文件夹,里面就存放着发布的 gradle 插件。


使用时,需要在根目录的 build.gradle 中添加如下代码:

buildscript {
    repositories {
      //首先需要配置本地的 maven 仓库地址,这里填写的是相对路径,也可以是全路径
        maven {
            url uri('repo') 
        }
    }
    dependencies {
        //然后,添加依赖的插件,形式是 groupId:artifactId:version
        //这些都是插件发布时,定义的名称
        classpath 'com.app.plugin:gradleplugin:1.0.0' 
    }
}

最后,在使用的 module 的 build.gradle 里,添加

apply plugin: 'com.app.plugin.myplugin' //这里就填写 .properties 文件的名称

这就完成了本地仓库的插件使用。重新构建工程后,效果如下:


远程仓库

发布插件到远程仓库的方法,我在网上搜索到几个方案,都不成功。

幸好 有 Gradle Plugins 这样一个门户网站,让我们可以快速发布 Gradle 的插件,它有一个使用的教程文档,在这里放上 地址 ,你也可以直接看文档。


现在来简单介绍如果使用:

  1. 首先需要在这个门户网站 https://plugins.gradle.org/ 中注册账户,它也可以支持 Github 账户登录。

  2. 然后在自己的账户界面,点击 API Keys ,获取 key 和 secret ,将他们 copy 到项目的 gradle.properties 文件中。

  3. 然后在将要发布的插件 module 的 build.gradle 文件中做如下配置:

    apply plugin: 'groovy'
    apply plugin: "com.gradle.plugin-publish"
    
    dependencies {
       compile gradleApi() //gradle sdk
       compile localGroovy() //groovy sdk
    
        //这里根据插件需要,添加对应的依赖
       compile 'com.android.tools.build:gradle:3.0.0'
       compile 'org.javassist:javassist:3.20.0-GA'
    }
    repositories {
       jcenter()
    }
    
    
    buildscript {
       repositories {
           maven {
               url "https://plugins.gradle.org/m2/"
           }
       }
       dependencies {
           classpath "com.gradle.publish:plugin-publish-plugin:0.9.7"
       }
    }
    
    repositories {
       mavenCentral()
       jcenter()
    }
    
    version = "1.0.0"    //配置插件的版本号
    group = "com.deemons.gradlePlugin"   //插件的群组,插件的classpath会用到
    
    pluginBundle {
    
       website = 'http://www.gradle.org/'
       vcsUrl = 'https://github.com/gradle/gradle'
       description = 'javassist for okbus'  //插件描述
       tags = ['okbus', 'javassist']  //插件的tag。可以通过这个在插件门户上搜索
    
       plugins {
           greetingsPlugin {
               id = 'com.deemons.bus'   //插件的id,到时候apply的插件id
               displayName = 'OkBus plugin'
           }
       }
    }
  4. 添加完成后并且同步后,右侧对应模块的 Tasks 目录下,会多出 plugin portal ,然后点击 publishPlugins 就完成发布了。


如果不出意外,插件就已经上传好了,这时候在 Plugins 上就可以搜索到自己的插件了。

点击进入,查看插件详情,里面会告诉你这个插件是如何使用的,是不是非常方便~


这篇文章只是简单的介绍了 gradle 插件的开发,但真正有难度的是插件的内容。比如,结合 AspectJ 或者javassist 完成功能强大的插件,例如 Tinker 、RePlugin、VirtualAPK 等。



参考

  • Gradle for Android
  • 拥抱 Android Studio
  • 如何使用Android Studio开发Gradle插件
  • 在AndroidStudio中自定义Gradle插件



你可能感兴趣的:(AOP)