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 :

    1. 记住先把第一步中app/build.gradle中的增加的内容删除。

    2. 做完所有的事情后,运行 ./gradlew hello也会打印那行语句,说明你成功了。

    3. 如果在发布插件时出现这个问题:

      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相关插件的源码了,还有很多路要走。加油。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,475评论 4 372
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,744评论 2 307
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 112,101评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,732评论 0 221
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,141评论 3 297
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,049评论 1 226
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,188评论 2 320
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,965评论 0 213
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,716评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,867评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,341评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,663评论 3 263
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,376评论 3 244
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,200评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,990评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,179评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,979评论 2 279

推荐阅读更多精彩内容