• 作者:老汪软件技巧
  • 发表时间:2024-11-26 04:01
  • 浏览量:

Gradle 插件是一种扩展 Gradle 构建工具功能的组件,我们可以使用它来协助我们打包、测试等。在开发过程中,我们离不开插件,比如创建一个Android项目,就需要如下的插件。

plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
}

屏幕截图 2024-11-20 213224.png

Gradle 插件和任务(Task)的区别

Gradle 任务是构建过程中的一个具体动作或操作单元,类似于一个个具体的功能代码。而 Gradle 插件则是组装这些 Task 的集合,类似于 SDK。

简单来说,Gradle 插件包含多个 Gradle 任务;Gradle 插件的功能是由一个个任务完成的。

插件插件的种类

插件分成三种:脚本插件(Script Plugins)、预编译脚本插件(Precompiled Script Plugins)、二进制插件(Binary Plugins)

自定义插件

上面提到过插件分为三种,它们之间的区别只是代码位置不同。为了体验插件编写和发布的全部流程,这里以二进制插件为例。首先我们先创建一个 module,如下图所示:

image.png

然后创建自己的插件类,我这里取名叫 MyPlugin,代码示例如下。可以看到,实现插件的功能很简单,我们只需要实现 Plugin 接口就可以了。

// 创建插件
class MyPlugin: Plugin<Project> {
    override fun apply(target: Project) {
        println("MyPlugin apply")
    }
}

然后在当前模块的 build.gradle 中使用 apply() 来应用插件,注意需要把这部分代码放在 build.gradle 文件的最前面。点击构建后,就可以看到插件的执行了。效果如下图所示:

image.png

从上图可以看到,gradle 的插件在被 apply 时就被运行。为了能参与后面的构建过程,我们一般在插件中注册任务,而不是在插件中直接执行逻辑操作。代码示例如下:

class MyPlugin : Plugin<Project> {
    override fun apply(target: Project) {
        println("MyPlugin apply")
        // 注册任务,执行操作
        target.tasks.register("myTask") {
            it.doLast {
                println("do something")
            }
        }
    }
}

自定义插件配置扩展

在Android中,我们常常看到如下的配置参数,这些都是Android插件构建需要的配置。

android {
    namespace = "com.example.demo"
    compileSdk = 34
    defaultConfig {
        applicationId = "com.example.demo"
        minSdk = 24
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }
    ...
}    

如果你想要仿照Android的插件,也为自己的插件加上配置参数,可以定义如下的配置类。注意,class 必须是 open 的

open class MyExtension {
    var tag: String? = null
    var user: MyUser? = null
    constructor(project: Project) {
        user = project.extensions.create("user", MyUser::class.java)
    }
}
// 嵌套的配置
open class MyUser {
    var name: String? = null
    var age: String? = null
}

然后在插件中注册并获取对应的配置,代码示例如下:

class MyPlugin : Plugin<Project> {
    override fun apply(target: Project) {
        println("MyPlugin apply")
        val extension = target.extensions.create("my_extension", MyExtension::class.java)
        target.tasks.register("fetchextension") {
            it.doLast {
                println("extension tag = ${extension.tag}")
                println("name: ${extension.user?.name} age: ${extension.user?.age}")
            }
        }
    }
}

完成这些步骤后,我们就可以在 build.gradle 中的配置如下:

my_extension {
    tag = "test_tag"
    user {
        name = "test_name"
        age = "test_age"
    }
}

注意;apply() 在 kotlin 脚本中有点问题,一直报获取不了自定义插件配置扩展的错误,需要本地发布依赖才能正常拉取配置。而同样的代码逻辑在 groovy 脚本中,使用 apply plugin 是没有问题的

打包

_插件文件_插件的格式都有哪些

要想我们编写的二进制插件打包,需要先设置如下配置:

plugins {
    id("java-gradle-plugin")
    id("org.jetbrains.kotlin.jvm")
}
gradlePlugin {
    plugins{
        create("myPlugin") {
            id = "com.example.plugin.MyPlugin"
            implementationClass = "com.demo.plugin.MyPlugin"
        }
    }
}

其中,id 是插件的唯一标识,就是我们应用插件时设置的,比如应用android插件 id("org.jetbrains.kotlin.android");implementationClass 则是我们插件的实现类的路径。完成这边步骤后,我们就可以对编写完成的插件进行发布了。

插件发布

插件发布分为本地发布和远端发布两种,下面将分别介绍。

本地发布

本地发布,顾名思义就是把打包的jar发布到本地仓库。要想实现这个功能,我们需要先在当前模块的 build.gradle 中设置如下依赖,并设置配置项。

id("maven-publish")
publishing {
    publications {
        create("mavenJava") {
            groupId = "com.example.plugin"
            artifactId = "MyPlugin"
            version = "1.0.0"
            from(components["java"])
        }
    }
    // 配置仓库
    repositories {
        maven {
            name = "localPluginRepository"
            url = uri("../local-plugin-repository")
        }
    }
}
dependencies {
    implementation("com.android.tools.build:gradle:7.3.1")
}

执行 ./gradlew publish 命令后,就可以在本地仓库看到发布成的包了。

image.png

如果我们想要在项目中使用这个包,需要在 setting.gradle 中设置本地仓库的位置,代码如下所示:

pluginManagement {
    repositories {
        maven {
            // 设置本地仓库的路径
            setUrl("./local-plugin-repository")
        }
        google {
            content {
                includeGroupByRegex("com\.android.*")
                includeGroupByRegex("com\.google.*")
                includeGroupByRegex("androidx.*")
            }
        }
        mavenCentral()
        gradlePluginPortal()
    }
    plugins {
        kotlin("jvm") version "2.0.0"
    }
}

同时在项目根目录中,依赖这个插件

buildscript {
    dependencies {
        classpath("com.example.plugin:MyPlugin:1.0.0")
    }
}

最后就可以在 build.gradle 中 apply 并配置 my_extension 的属性了。

plugins {
    alias(libs.plugins.android.application)
    alias(libs.plugins.jetbrains.kotlin.android)
    id("com.example.plugin.MyPlugin")
}
android {
   ...
}
my_extension {
    tag = "test_tag"
    user {
        name = "test_name"
        age = "test_age"
    }
}

远端发布

远端发布流程可以看 Yechaoa 大佬的 【Gradle-9】Gradle插件发布指南。这篇文章已经讲得很详细了,我就不重复介绍了。

参考