Android-编译时插件Plugin

Android-编译时插件Plugin

现如今,MAD (Modern Android Development) 是一定离不开 Gradle 的;作为 Google 大力支持的新一代编译和依赖管理工具,Gradle 比早期的 ANT 及 Maven 有太多先进的地方,当然这不是本文的重点。而 Gradle 在作为编译工具时,Plugin 就是其强大的因素之一,可以说 Gradle 为编译过程提供的高自由度定制化,正是以 Plugin 为基础的。

1. Gradle和Plugin

要介绍 Gradle Plugin,就不得不提到 Gradle 和 Plugin 的关系,简单来说:Plugin 决定了 Gradle 的工作内容

一个 Android 项目几乎不可能完全仅通过本地的源码构建,除了开发过程中需要添加的依赖(包括 Android 原生的组件等)之外、还需要根据需要定制化编译脚本。如果每一个依赖或者每一个编译脚本都需要手动维护,会极大地增加开发成本,而 Gradle 同时具备「编译工具」和「依赖管理」的功能正是为了解决这一问题。Gradle 定制了一系列标准,通过代码的形式维护项目的依赖管理和编译脚本,尽可能将这些与业务开发无关的事情剥离出来,并且带来了一个非常重要的好处:自动化。因此,开发人员可以专注于编写业务代码,编译和构建的事情都可以交给流水线或其他工具自动化运行,例如定时构建、多渠道并行构建、自动化构建发布等等。

因此,Gradle 是一个工具,它可以执行用于编译或依赖管理的脚本,并为项目提供开发环境。但 Gradle 是一个纯粹的工具。抽象地说,Gradle 本身只具备一些基础的执行能力,负责执行开发人员定义的脚本功能,而 Plugin,则是定义了 Gradle 执行方式的一个载体。Plugin 可以包含一系列 Gradle 的可执行脚本,并且在注册给 Gradle 后,将由 Gradle 创建,因此 Plugin 具有 Gradle 的上下文环境,可以灵活地操作各项 Gradle 执行任务。

很粗略地说,Gradle 与 Plugin 就像 JVM 与 Java 类一样。


2. 自定义Plugin

为了更方便阅读 Gradle 的源码或者查询 API,可以添加 Gradle 自己的接口依赖:

1
2
3
4
5
dependencies {
implementation 'com.android.tools.build:gradle:x.x.x' // 根据需要选择版本号
implementation gradleApi()
implementation localGroovy()
}

自定义 Plugin 只需要创建一个 Plugin<Project> 的子类、并声明在配置文件中即可,Gradle Plugin 支持使用 Groovy 或 Kotlin 编写。以 Groovy 为例(其语法和规范与 Java 几乎一致):

  • 创建 Groovy 代码目录及对应的包结构。
  • 创建一个 Plugin 的 Groovy 类。
  • 创建用于注册 Plugin 的配置文件。

创建后的文件及目录结构大致为:

1
2
3
4
5
6
7
8
9
10
11
module_demo
└─ src
└─ main
├─ groovy
│ └─ priv.demo
│ └─ DemoPlugin.groovy
├─ java
└─ resources
└─ META-INF
└─ gradle-plugins
└─ demo-plugin-custom-name.properties

(1)编写 DemoPlugin.groovy

1
2
3
4
5
6
7
8
9
10
11
12
package priv.demo

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

class DemoPlugin implements Plugin<Project> {

@Override
void apply(Project project) {
System.out.println("This is the demo plugin.")
}
}

(2)将 Plugin 注册到 demo-plugin-custom-name.properties

1
implementation-class=priv.demo.DemoPlugin

注意:

  • 该注册文件的文件名 XXX.properties 就是最终可用的 Plugin 名称,可以自定义;
  • Plugin 的 Groovy 类名只是为了编译生成 Plugin;
  • 注册文件 XXX.propertyies 必须放在 resources/META-INF/gradle-plugins/ 中,文件内声明的就是 Plugin 的 Groovy 类全地址。

(3)在其他 Module 的 build.gradle 文件中应用 Plugin:

1
2
// 应用的 Plugin 名对应的是注册文件的文件名。
apply plugin: "demo-plugin-custom-name"

(4)Sync Gradle,即可在 Log 中看到日志。


3. Plugin常见操作


4. Plugin常见问题


参考文献