编写 Gradle Plugin

1,480 阅读2分钟

Plugin 的最基本写法,写在 build.gradle 里:

class PluginDemo implements Plugin<Project> {
    @Override
    void apply(Project target) {
        println 'Hello author!'
    }
}

apply plugin: PluginDemo
  • Extension
class ExtensionDemo {
    def name = 'Li'
}

class PluginDemo implements Plugin<Project> {
    @Overridevoid apply(Project target) {
            def extension = target.extensions.create('extension', ExtensionDemo)
            target.afterEvaluate {
                println "Hello ${extension.name}!"
            }
    }
}

apply plugin: PluginDemo

extension {
    name 'xuanlin'
}

写在 buildSrc 目录下:

  • 目录结构

飞书20220106-103918.jpg

  1. resources/MEAT-INF/gradle-plugins/xx.properties 中的 xx 是插件的名称,例如 com.test.plugin.properties最终应用插件的代码应该是:
apply plugin: 'com.test.plugin'
  1. .properties中只有一行,格式是:
implementation-class=com.test.plugin.DemoPlugin
  • 关于 buildSrc 目录:
  1. 这是 gradle 的一个特殊目录,这个目录会自动被执行,即使不配置进settings.gradle,我们甚至可以删除 buildSrc 中的 build.gradle
  2. buildSrc 的执行早于任何一个 project,在低版本 gradle 中也早于 settings.gradle,高版本 gradle 中晚于 settings.gradle
  3. buildSrc 所配置出来的 Plugin 会被自动添加到编译过程中的每一个 project 的 classpath,因此它们可以直接使用 apply plugin: 'xxx' 的方式来便捷应用这些 plugin
  4. settings.gradle 中如果配置了 ':buildSrc',buildSrc 目录会被当做是子 Project,因此会被执行两遍,且会导致无法使用 Plugin 和 Project 对象。所以在 settings.gradle 里面应该删掉':buildSrc' 的配置

单独模式

  1. Create New Module -> Java or Kotlin Library
  2. 修改 module 的 build.gradle
plugins {
    id 'java-library'
    id 'maven-publish'
}

dependencies {
    compileOnly gradleApi()
}

java {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            groupId 'com.test.plugin'
            artifactId 'plugin'
            version '1.0.0'
            from components.java
        }
    }
    repositories {
        maven {
            url uri('./Android/repos')
        }
    }
}
  1. 编写 Gradle Plugin,同 buildSrc
  2. 发布到本地 maven 仓库。命令如下:
./gradlew publish
  1. 引用本地 maven 仓库,并添加 classpath
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    repositories {
        google()
        mavenCentral()
        maven {
            url uri('./plugin/Android/repos')
        }
    }
    dependencies {
        classpath "com.android.tools.build:gradle:7.0.1"
        classpath group: 'com.test.plugin', name: "plugin", version: '1.0.0'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}
  1. 使用插件
plugins {
    id 'com.android.application'
    id 'com.test.plugin'
}

注意: 创建 module 添加 compileOnly gradleApi() 同步后,会报 Build was configured to prefer settings repositories over project repositories but repository 'Gradle Libs' was added by unknown code,需要修改 setting.gradle,删除 repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)

dependencyResolutionManagement {
    // repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        jcenter() // Warning: this repository is going to shut down soon
    }
}