Gradle插件开发-入门

1,145 阅读3分钟

Android Gradle的插件简介

Gradle的插件是实现了org.gradle.api.Plugin接口的类,并且会有自己的plugin id。

在Android工程中,我们可以在每个模块的build.gradle文件中看到application或者libaray的插件:
apply plugin: 'com.android.application'apply plugin: 'com.android.library'

这两个插件帮我构建apk或者aar,其实分别对应以下两个类:
com.android.build.gradle.AppPlugincom.android.build.gradle.LibraryPlugin

自定义插件

自定义的插件,主要是看插件里的task有什么作用。
接下来写一个最简单的插件来打印一行练练手,需要的结构目录:

  1. 先创建一个android工程,名字就取FirstPlugin。
  2. 创建如下图的目录和文件即可,共三个文件。

解释:

1. groovy

groovy首先插件一般习惯用groovy语法来写,所以创建一个groovy目录,com.xfz.plugin是普通目录,正在的插件是目录里的PrintPlugin.groovy,代码非常简单,继承了Plugin,在apply方法中进行打印

package com.xfz.plugin

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

class PrintPlugin implements Plugin<Project> {

   void apply(Project project) {
      println("first gradle plugin ==============")
   }
}

2. properties

接下来是myFirstPlugin.properties文件,该文件名就是这个plugin的id,
后面引用方式为apply plugin: 'myFirstPlugin'
properties文件内部写上引用实现的插件类即可:

implementation-class=com.xfz.plugin.PrintPlugin

3. gradle

build.gradle主要两部分,一部分是引用gradle插件和依赖gradle

apply plugin: 'groovy'

dependencies {
   implementation gradleApi()
   implementation 'com.android.tools.build:gradle:4.2.2'
}

repositories {
   google()
   mavenCentral()
}

另一部分是上传到maven库,使用uploadArchives,这里简单的配置了本地maven库

apply plugin: 'maven'

//group和version在后面使用自定义插件的时候会用到
group = 'com.xfz.plugin'
version = '1.0.0'

uploadArchives {
   repositories {
      mavenDeployer {
         /*
         repository(url: "http://www.xxx.com/repos") {
            authentication(userName: "admin", password: "admin")
         }*/

         //mac下默认的本地的Maven地址
         repository(url: "file:///Users/xufangzhen/.m2/repository")
      }
   }
}

在settings.gradle中写上include ':print'

最后执行命令上传到仓库:./gradlew uploadArchives

maven本地仓库配置

mac环境下:

  • 首先下载maven brew install maven
  • 其次配置环境变量:
# maven
export M2_HOME=/usr/local/Cellar/maven/3.8.2/libexec
export PATH=$PATH:$M2_HOME/bin
  • 输入mvn -v 查看是否成功

自定义插件的使用

在需要使用的工程中,在build.gradle中引用,需要以下三步
引用后构建项目时,就打印出“first gradle plugin ==============”

//1.引用插件
apply plugin: 'myFirstPlugin'

buildscript {
    repositories {
        google()
        mavenCentral()
        maven {
            //2.Maven仓库地址
            url "file:///Users/xufangzhen/.m2/repository"
        }
    }
    dependencies {
        //3.groupo:module:version
        classpath 'com.xfz.plugin:print:1.0.0'
    }
}

在主工程中开发并使用插件

了解了新建一个插件工程来开发插件,如果在自己的工程中开发一个插件,有几点不同:

  1. 插件模块需要在buildSrc中,不需要properties,gradle中也无须上传maven,settings中也不需要引用include。
  2. 引用插件使,直接引用到插件类,不带引号
apply plugin: com.xfz.plugin.PrintPlugin

上传aar的插件

我们在组件化开发中,会有很模块,这些模块会打包成aar上传到maven库,因此我们可以把这个上传的任务封装成一个插件,而不需要每个地方都配置uploadArchives

根据上面的介绍,先看下整体的项目结构:一个插件和一个任务

AarUploadTask继承自upload

代码如下:三个变量groupId、artifactId、version用来配置aar的名字版本,如果非snapshot版本,则使用tag来命名aar

package com.xfz.plugin.upload

import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.Upload

class AarUploadTask extends Upload {
   String groupId = null
   String artifactId = null
   String version = null

   @TaskAction
   protected void upload() {
      if (groupId == null || artifactId == null) {
         return
      }
      //配置仓库,该demo设置本地maven库
      repositories {
         mavenDeployer {
            repository url: "file:///Users/xufangzhen/.m2/repository"
            //计算版本信息,如果是snapshot版本,就直接拿版本号,如果是正式版,拿最后tag作为版本号
            pom.version = getVersionName()
            pom.artifactId = artifactId
            pom.groupId = groupId
         }
      }
      //开始上传
      println "start upload " + groupId + ":" + artifactId + ":" + version
      super.upload()
   }

   /**
    * ./gradlew clean -PisSnapshot=false :base:aarUpload
    **/
   def getVersionName() {
      def isSnapshot = ""
      if (project.hasProperty("isSnapshot")) {
         isSnapshot = project.property("isSnapshot")
      }
      //如果是snapshot且版本号不为空,就用版本号-SNAPSHOT命名
      if (Boolean.parseBoolean(isSnapshot) && version != null) {
         return version + '-SNAPSHOT'
      } else if (version != null && version.length() > 0) {
         return version
      } else {
         //否则使用最后提交的tag名命名
         return 'git describe --tags --abbrev=0'.execute().text.trim()
      }
   }
}

AarUploadPlugin实现了Plugin

package com.xfz.plugin.upload

import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.tasks.bundling.Jar

class AarUploadPlugin implements Plugin<Project> {
   void apply(Project target) {
      target.pluginManager.apply 'maven'
      def aarUploadTask = target.task('aarUpload', type: AarUploadTask, dependsOn: 'assemble')
      //设置源码上传
      aarUploadTask.doFirst {
         target.task(type: Jar) {
            classifier = 'sources'
            from android.sourceSets.main.java.srcDirs
         }
      }
      aarUploadTask.configuration = target.configurations.archives
   }
}

使用方式

apply plugin: 'aar.upload'

aarUpload {
    artifactId = 'base' //aar名字
    version = '1.3.0' //版本
    groupId = 'com.xfz.plugin' //groupId
}

//最外层build.gradle里设置classpath