深度探索Gradle自动化构建技术(四、自定义 Gradle 插件)

本文详细介绍了Gradle插件的编写,包括脚本插件、在buildSrc目录下创建插件、自定义Extension和Task、利用Variants及Transform API进行构建过程的扩展。此外,还讲解了如何发布和调试Gradle插件,帮助开发者更好地理解和应用Gradle自动化构建技术。
摘要由CSDN通过智能技术生成

一、Gradle 插件概述

自定义 Gradle 插件的本质就是把逻辑独立的代码进行抽取和封装,以便于我们更高效地通过插件依赖这一方式进行功能复用

而在 Android 下的 gradle 插件共分为 两大类,如下所示:

  • 1、脚本插件同普通的 gradle 脚本编写形式一样,通过 apply from: 'JsonChao.gradle' 引用

  • 2、对象插件通过插件全路径类名或 id 引用,它主要有 三种编写形式,如下所示:

    • 1)、在当前构建脚本下直接编写

    • 2)、在 buildSrc 目录下编写

    • 3)、在完全独立的项目中编写

下面????,我们就先来看看如何编写一个脚本插件。

二、脚本插件

同普通的 gradle 脚本编写形式一样,我们既可以写在 build.gradle 里面,也可以自己新建一个 gradle 脚本文件进行编写。

class PluginDemo implements Plugin<Project> {

    @Override
    void apply(Project target) { 
        println 'Hello author!'
    } 
}
复制代码

然后,在需要使用的 gradle 脚本中通过 apply plugin:pluginName 的方式即可引用对应的插件。

apply plugin: PluginDemo
复制代码

三、运用 buildSrc 默认插件目录

在完成几个自定义 Gradle 插件之后,我发现 在 buildSrc 目录下编写插件的方式是开发效率最高的,首先,buildSrc 是默认的插件目录,其次,在 buildSrc 目录下与独立工程的插件工程一样,也能够发布插件,这里仅仅只需对某些配置做一些调整即可,下面,我们就来看看如何来创建一个自定义 Gradle 插件。

1、创建一个能运行起来的空 Plugin

首先需要了解的是,buildSrc 目录是 gradle 默认的构建目录之一,该目录下的代码会在构建时自动地进行编译打包,然后它会被添加到 buildScript 中的 classpath 下,所以不需要任何额外的配置,就可以直接被其他模块中的 gradle 脚本引用。此外,关于 buildSrc,我们还需要注意以下 两点

  • 1)、buildSrc 的执行时机不仅早于任何⼀个 project(build.gradle),而且也早于 settings.gradle

  • 2)、settings.gradle 中如果配置了 ':buildSrc' ,buildSrc ⽬录就会被当做是子 Project , 因会它会被执行两遍。所以在 settings.gradle 里面应该删掉 ':buildSrc' 的配置

插件 moudle 创建三部曲

1)、新建一个 module,并将其命名为 buildSrc。这样,Gradle 默认会将其识别会工程的插件目录

2)、src 目录下删除仅保留一个空的 main 目录,并在 main 目录下新建 1 个 groovy 目录与 1 个 resources 目录

3)、将 buildSrc 中的 build.gradle 中的所有配置删去,并配置 groovy、resources 为源码目录与相关依赖即可。配置代码如下所示:

apply plugin: 'groovy'

repositories {
    google()
    mavenCentral()
    jcenter()
}

dependencies {
    // Groovy DSL
    implementation localGroovy()
    // Gradle DSL
    implementation gradleApi()

    // Android DSL
    implementation 'com.android.tools.build:gradle:3.6.2'

    // ASM V7.1
    implementation group: 'org.ow2.asm', name: 'asm', version: '7.1'
    implementation group: 'org.ow2.asm', name: 'asm-commons', version: '7.1'

}

sourceSets {
    main {
        groovy {
            srcDir 'src/main/groovy'
        }

        resources {
            srcDir 'src/main/resources'
        }
    }
}
复制代码

插件创建二部曲

1)、首先,在我的 main 目录下创建一个递归文件夹 "com.json.chao.study",里面直接新建一个名为 CustomGradlePlugin 的普通文件。然后,在文件中写入 'class CustomGradlePlugin' ,这时 CustomGradlePlugin 会被自动识别为类,接着将其实现 Plugin 接口,其中的 apply 方法就是插件被引入时要执行的方法,这样,自定义插件类就基本完成了,CustomGradlePlugin 类的代码如下所示:

/**
 * 自定义插件
 */
class CustomGradlePlugin implements Plugin<Project> {

    /**
     * 插件被引入时要执行的方法
     * @param project 引入当前插件的 project
     */
    @Override
    void apply(Project project) {
        println "Hello plugin..." + project.name
    }
}
复制代码

2)、接着,在 resources 目录下创建一个 META-INF.gradle-plugins 的递归目录,里面新建一个 "com.json.chao.study.properties" 文件,其中 '.properties' 前面的名字即为 自定义插件的名字,在该文件中,我们需要标识该插件对应的插件实现类,代码如下所示:

implementation-class=com.json.chao.study.CustomGradlePlugin
复制代码

这样,一个最简单的自定义插件就完成了。接着,我们直接在 app moudle 下的 build.gradle 文件中使用 'apply plugin: 'com.json.chao.study' 引入我们定义好的插件然后同步工程即可看到如下输出:

...
> Configure project :app
Hello plugin...app
...
复制代码

可以看到,通过 id 引用的方式,我们可以隐藏类名等细节,使得插件的引用变得更加容易

2、使用自定义 Extension 与 Task

1、自定义 Extension

在 深度探索 Gradle 自动化构建技术(三、Gradle 核心解密) 一文中我们讲解了如何创建一个版本信息管理的 task,这里我们就可以直接将它接入到 gradle 的构建流程之中。

为了能让 App 传入相关的版本信息和生成的版本信息文件路径,我们需要一个用于配置版本信息的 Extension,其实质就是一个实体类,如下所示:

/*
 * Description: 负责 Release 版本管理的扩展属性区域
 *
 * @author quchao
 */
class ReleaseInfoExtension {

    String versionName;
    String versionCode;
    String versionInfo;
    String fileName;
}
复制代码

然后,在我们的 CustomGradlePlugin 的 apply 方法中加入下面代码去创建用于设置版本信息的扩展属性,如下所示:

// 创建用于设置版本信息的扩展属性
project.extensions.create("releaseInfo", ReleaseInfoExtension.class)
复制代码

在 project.extensions.create 方法的内部其实质是 通过 project.extensions.create() 方法来获取在 releaseInfo 闭包中定义的内容并通过反射将闭包的内容转换成一个 ReleaseInfoExtension 对象

最后,我们就可以在 app moudle 的 build.gradle 脚本中使用 releaseInfo 去配置扩展属性,代码如下所示:

releaseInfo {
    versionCode = "1"
    versionName = "1.0.0"
    versionInfo = "第一个版本~"
    fileName = "releases.xml"
}
复制代码

2、自定义 Task

使用自定义扩展属性 Extension 仅仅是为了让使用插件者有配置插件的能力。而插件还得借助自定义 Task 来实现相应的功能,这里我们需要创建一个更新版本信息的 Task,我们将其命名为 ReleaseInfoTask,其具体实现代码如下所示:

/**
 * 更新版本信息的 Task
 */
class ReleaseInfoTask extends DefaultTask {

    ReleaseInfoTask() {
        // 1、在构造器中配置了该 Task 对应的 Task group,即 Task 组,并为其添加上了对应的描述信息。
        group = 'version_manager'
        description = 'release info update'
    }

    // 2、在 gradle 执行阶段执行
    @TaskAction
    void doAction() {
        updateVersionInfo();
    }

    private void updateVersionInfo() {
        // 3、从 realeaseInfo Extension 属性中获取相应的版本信息
        def versionCodeMsg = project.extensions.releaseInfo.versionCode;
        def versionNameMsg = project.extensions.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值