使用Java开发Gradle Plugin基础流程

/ 0评 / 0

使用Java开发Gradle Plugin基础流程

在Android开发的过程中,我们经常使用如下方法在项目中加入插件

app/build.gradle
//新版本
plugins {
    id 'com.jfrog.bintray' version '1.8.5'
}

//旧版本
apply plugin: 'com.android.library'

plugins{}块这种方式引入的插件来自Gradle官方插件库

使用apply plugin方式引入的插件,需要在dependencies中指定一下

//Project Root/build.gradle

buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.1.1"
        classpath "org.gradle.sample:cus:1.0.0-snapshots"
    }
}

创建项目

首先在项目中新建一个Java Module,可以使用Java或Kotlin进行开发

改造流程

1、更改build.gradle文件

plugins {
    id 'java'
    id 'org.jetbrains.kotlin.jvm'
    id 'java-gradle-plugin'
    id 'maven-publish'
}

dependencies {
    //gradle插件相关api
    implementation gradleApi()
}

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

gradlePlugin {
    plugins {
        //每个插件块的名称不影响插件配置,但需要为每个提供的插件提供唯一的名称
        threadAop {
            //插件的id,期望唯一
            id = 'com.thread.plugin.aop'
            //插件的实现类
            implementationClass = 'com.thread.plugin.ThreadPluginPlugin'
            //插件名字
            displayName = 'Thread AOP'
            //插件描述
            description = '随便写点描述吧'
        }
    }
}

注意

com.android.tools.build:gradle的版本会影响接入方的Gradle版本

比如4.1.1则要求Gradle版本在6.5.0以上!!!对应关系请看官方文档

参考文档

Gradle Plugin Development Plugin

Publishing Plugins to the Gradle Plugin Portal

本地发布

因为gradle项目没法像普通的Module进行直接依赖,所以需要发布以后才能使用,本地联调阶段,其实放本地就可以了

1、 更改build.gradle文件,新增本地发布插件功能,在 Gradle 6.2 之后,就完全被弃用了

plugins {
    id 'java-gradle-plugin'
    //新增maven
    id 'maven'
}

uploadArchives {
    repositories {
        mavenDeployer {
            //设置插件的GAV参数
            pom.groupId = 'org.gradle.sample'
            pom.artifactId = 'cus'
            pom.version = '1.0.0-snapshots'
            //文件发布到下面目录
            repository(url: uri("${rootProject.projectDir}/repo"))
        }
    }
}

gradlePlugin {
    plugins {
        testPlugin {
            id = 'org.gradle.sample.simple-plugin'
            implementationClass = 'org.learn.plugintest.MyClass'
            displayName = 'Android Code Coverage Plugin'
            description = 'A gradle plugin for Android which can inspect incremental code test coverage'
        }
    }
}

dependencies {
    implementation 'com.android.tools.build:gradle:4.1.1'
}

然后执行uploadArchives命令即可在本地发布,在项目根目录的repo文件夹下

发布到gradle官方插件,可以参考Publishing Plugins to the Gradle Plugin Portal

1、使用maven-publish发布

plugins {
    id 'java'
    id 'org.jetbrains.kotlin.jvm'
    id 'java-gradle-plugin'
    id 'maven-publish'
}

dependencies {
    //gradle插件相关api
    implementation gradleApi()
}

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

gradlePlugin {
    plugins {
        //每个插件块的名称不影响插件配置,但需要为每个提供的插件提供唯一的名称
        threadAop {
            //插件的id,期望唯一
            id = 'com.thread.plugin.aop'
            //插件的实现类
            implementationClass = 'com.thread.plugin.ThreadPluginPlugin'
            //插件名字
            displayName = 'Thread AOP'
            //插件描述
            description = '随便写点描述吧'
        }
    }
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            groupId = 'com.thread.plugin'
            artifactId = 'aop'
            version = '1.0.0-snapshots'
            from components.java
        }
    }

    repositories {
        maven {
            //定义仓库名【可选】  publishMavenJavaPublicationToLocalRepoRepository
            name "localRepo"
            // 文件发布到项目根目录下的repo目录
            url = uri("${rootProject.projectDir}/repo")
        }
        // 可选多个,上传指定位置并添加密码
        // maven {
        //     url = "https://xxxx"
        //     credentials {
        //         it.username = "username"
        //         it.password = "password"
        //     }
        // }
    }
}

file

自动生成的任务如上,执行publishAllPublicationsToLocalRepoRepository即可,官方文档

2、使用插件

添加本地仓库

//新版本Gradle
buildscript {
    dependencies {
        classpath "com.thread.plugin:aop:1.0.0-snapshots"
    }
}

plugins {
    id 'com.android.application' version '8.0.2' apply false
    id 'com.android.library' version '8.0.2' apply false
    id 'org.jetbrains.kotlin.android' version '1.8.20' apply false
}

//旧版本👇🏻
//Project Root/build.gradle
buildscript {
    repositories {
        google()
        jcenter()
        //本地仓库地址
        maven { url uri("${rootProject.projectDir}/repo") }
    }
    dependencies {
        //上面上传的地址
        classpath "org.gradle.sample:cus:1.0.0-snapshots"
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

应用插件

//app/build.gradle

plugins {
    //gradlePlugin中指定的id
    id 'org.gradle.sample.simple-plugin' version '1.0.0-snapshots'
}

插件调试

参考来源:https://segmentfault.com/a/1190000041856822#item-3-6

在开发插件的过程一定需要调试,除了通过日志调试,我们也有断点调试的需求。这里总结两个方法:方法 1 虽然只支持调试简单执行任务,但已经能满足大部分需求,而且相对简单。而方法 2 支持命令行添加参数。

方法 1(简单): 直接提供 Android Studio 中 Gradle 面板的调试功能,即可调试插件。如下图,我们选择与插件功能相关的 Task,并右键选择 Debug 执行。

file

方法 2: 通过配置 IDE Configuration 以支持调试命令行任务,具体步骤:

1、创建 Remote 类型 Configuration:

file

2、执行命令: ./gradlew Task -Dorg.gradle.debug=true --no-daemon (开启 Debug & 不使用守护进程),执行后命令行会进入等待状态:

file

3、Attach Debug: 点击调试按钮,即可开始断点调试。

file

4.2 调试技巧
一些调试技巧:

引用插件源码: 在开发阶段可以直接本地依赖插件源码,而不需要将插件发布到 Maven 仓库,只需要在 build.gradle 文件中修改配置:
项目 build.gradle

buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        // For Debug 需要点击(通过这种方法,需要首先执行插件的build任务生成一下jar包)
        // 不然会Could not create task ':app:kaptSheinDebugKotlin'.
        classpath project(":easyupload")
        // classpath "com.pengxr:easyupload:1.0.0"
    }
    ...
}

插件代码开关: 由于 Plugin#apply 中的代码在配置阶段执行,如果其中的代码有问题就会出现 Sync 报错。又因为编译插件代码需要先 Sync,只能先将工程中所有使用插件的代码注释掉,重新编译插件模块,再将注释修改回来。真麻烦!我们还是加一个开关吧,例如:
gradle.properties

ENABLED=true
模块 build.gradle

if (ENABLED.toBoolean()) {
    apply plugin: 'com.pengxr.easyupload'
    upload {
        name = "123"
    }
}

参考链接:

Android Gradle 插件开发入门指南(一)

gradle doc

官方文档

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注