日志

Android gradle 自定义插件

 来源    2020-05-23    0  

Gradle 的插件有三种打包方式:

  • 构建脚本:插件逻辑写在 build.gradle 中,适用于逻辑简单的任务,但是该方式实现的插件在该构建脚本之外是不可见的,只能用于当前脚本。
  • buildSrc项目:根据语言插件代码放在 rootProjectDir/buildSrc/src/main/groovy 目录中或者 rootProjectDir/buildSrc/src/main/java 或者rootProjectDir/buildSrc/src/main/kotlin,该插件对于该项目中构建使用的每个构建脚本都是可见的,适用于逻辑复杂但又不需要对外可见的插件

  • 独立项目:一个独立的 Groovy/Java/Kotlin 项目,该项目生成并发布一个 jar 然后可以在多个版本中使用它并与他人共享,并且此 jar 包可能包含一些插件,或者将多个相关的任务类捆绑到单个库中

接下来我们先从基本的构建脚本中的插件开始 

1、构建脚本:

创建 Gradle 插件,需要创建一个实现 Plugin 接口的类,当插件应用于项目时,Gradle 会创建插件类的实例并调用实例的 apply() 方法,如果需要的话,插件还可以用于配置项目

把插件变得可配置,添加一些简单扩展属性到 project 上,比如可以添加一个 greeting 扩展对象到 project 上,这就允许我们去配置 greeting 对象。

文件是 build.gradle:

class GreetingPluginExtension {
    String message = 'Hello from GreetingPlugin'
}

class GreetingPlugin implements Plugin<Project> {
    void apply(Project project) {
        // Add the 'greeting' extension object
        def extension = project.extensions.create('greeting', GreetingPluginExtension)
        // Add a task that uses configuration from the extension object
        project.task('hello') {
            doLast {
                println extension.message
            }
        }
    }
}

apply plugin: GreetingPlugin

// Configure the extension
greeting.message = 'Hi from Gradle'

2、独立项目 

创建Gradle Module

AndroidStudio中是没有新建类似Gradle Plugin这样的选项的,那我们如何在AndroidStudio中编写Gradle插件,并打包出来呢?

  1. 首先,你得新建一个Android Project

  2. 然后再新建一个 Module,这个 Module用于开发 Gradle 插件,同样,Module 里面没有 gradle plugin 给你选,但是我们只是需要一个“容器”来容纳我们写的插件,因此,你可以随便选择一个 Module 类型(如 Phone & Tablet Module 或 Android Librarty ),因为接下来一步我们是将里面的大部分内容删除,所以选择哪个类型的 Module 不重要。

  3. 将 Module 里面的内容删除,只保留 build.gradle 文件和 src/main 目录。

  4. 由于 gradle 是基于 groovy,因此,我们开发的 gradle 插件相当于一个 groovy 项目。所以需要在 main 目录下新建 groovy 目录

  5. groovy 又是基于Java,因此,接下来创建groovy的过程跟创建java很类似。在 groovy 新建包名,如:com.sjq.greetplugin,然后在该包下新建groovy文件,通过  new->file→GreetingPlugin.groovy 来新建名为 GreetingPlugin 的 groovy 文件。一定是要有.groovy 后缀文件。

  6. 为了让我们的 groovy 类申明为 gradle 的插件,新建的 groovy 需要实现 org.gradle.api.Plugin 接口。

如下所示:

package com.sjq.greetplugin  // 包名一定要有,不然打包不会打进对应包里去,很可能就会出现类找不到的情况。

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

class GreetingPlugin implements Plugin<Project> {
    @Override
    void apply(Project project) {
        project.task("publishPluginTest"){ // task 名字
            doLast {
                println("新内容是:null")
            }
        }
    }
}

定义好了自己的 gradle 插件类,接下来就是告诉 gradle,哪一个是我们自定义的插件类,因此,需要在 main 目录下新建 resources 目录,然后在resources 目录里面再新建 META-INF 目录,再在 META-INF 里面新建 gradle-plugins 目录。最后在 gradle-plugins 目录里面新建 properties 文件,注意这个文件的命名,你可以随意取名,但是后面使用这个插件的时候,会用到这个名字。比如,你取名为 com.sjq.gradle.properties,而在其他build.gradle 文件中使用自定义的插件时候则需写成: 

apply plugin: 'com.sjq.greetplugin'

然后在com.hc.gradle.properties文件里面指明你自定义的类

implementation-class=com.sjq.greetplugin.GreetingPlugin // 注意后面跟的是插件名字,注意大小写

此处我们还是采用包名,方便记忆。

到这里后,整个目录结果如下图所示:

因为我们要用到 groovy 以及后面打包要用到 maven, 所以在我们自定义的 Module 下的 build.gradle 需要添加如下代码:

apply plugin: 'groovy'
apply plugin: 'maven'

dependencies {
//gradle sdk
compile gradleApi()
//groovy sdk
compile localGroovy()
}

repositories {
mavenCentral()
}

打包到本地Maven

前面我们已经自定义好了插件,接下来就是要打包到 Maven 库里面去了,你可以选择打包到本地,或者是远程服务器中。在我们自定义 Module 目录下的 build.gradle 添加如下代码:

//group和version在后面使用自定义插件的时候会用到
group='com.hc.plugin'
version='1.0.0'

uploadArchives {
    repositories {
        mavenDeployer {
            //提交到远程服务器:
           // repository(url: "http://www.xxx.com/repos") {
            //    authentication(userName: "admin", password: "admin")
           // }
            //本地的Maven地址设置为../repos
            repository(url: uri('../repos'))
        }
    }
}

其中,group 和 version 后面会用到,我们后面再讲。虽然我们已经定义好了打包地址以及打包相关配置,但是还需要我们让这个打包 task 执行。点击 AndroidStudio 右侧的 gradle 工具,如下图所示:

 

可以看到有 uploadArchives 这个 Task,双击 uploadArchives 就会执行打包上传啦!执行完成后,去我们的 Maven 本地仓库查看一下:

 

其中,com/sjq/greetplugin 这几层目录是由我们的 group 指定,myplugin 是模块的名称,1.0.0 是版本号( version 指定)。 

使用自定义的插件

接下来就是使用自定义的插件了,一般就是在 app 这个模块中使用自定义插件,因此在 app 这个 Module 的 build.gradle 文件中,需要指定本地 Maven 地址、自定义插件的名称以及依赖包名。简而言之,就是在 app 这个 Module 的 build.gradle 文件中后面附加如下代码:

buildscript {
    repositories {
        maven {//本地Maven仓库地址
            url uri('../repos')
        }
    }
    dependencies {
        //格式为-->group:module:version
        classpath 'com.sjq.greetplugin:GreetingPlugin:1.0.0'
    }
}
//com.sjq.greetplugin 为 resources/META-INF/gradle-plugins 下的 properties 文件名称
apply plugin: 'com.sjq.greetplugin'

在当前目录下输入命令行:

./gradlew -q publishPluginTest

运行结果:

3、开发只针对当前项目的Gradle插件

前面我们讲了如何自定义 gradle 插件并且打包出去,可能步骤比较多。有时候,你可能并不需要打包出去,只是在这一个项目中使用而已,那么你无需打包这个过程。

只是针对当前项目开发的 Gradle 插件相对较简单。步骤之前所提到的很类似,只是有几点需要注意:

新建的 Module 名称必须为 BuildSrc,无需 resources 目录

其中,build.gradle 内容为:

// 依赖groovy插件
plugins {
    id 'groovy'
}

dependencies {
    implementation gradleApi()
    implementation localGroovy()
}

CustomPluginB 内容是

package com.sjq.happy.myplugin

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

// 在单独的groovy文件中定义插件类
class CustomPluginB implements Plugin<Project> {

    @Override
    void apply(Project project) {
        project.task('CustomPluginTaskB') {
            doFirst {
                println 'This is custom plugin TaskB'
            }
        }
    }
}

app这个Module中如何使用呢?直接在app的build.gradle下加入

import com.sjq.happy.myplugin.CustomPluginB

在输入命令行:

./gradlew -q CustomPluginTaskB

结果如下图所示:

 

相关文章
android – Gradle自定义存储库和依赖项解析
问答我正在开发的项目需要scribe-java和crashlytics库.这两个库都可以从自定义存储库中获得. build.gradle看起来像: buildscript { repositories { ...
1
使用Java创建Gradle自定义插件
问答我正在使用Gradle创建一个构建过程,我想提供一个使用Java代码的插件. Gradle plugin documentation说这是可能的: You can implement a custom ...
2
android – Gradle Artifactory插件 – 如何从项目中的多个模块发布工件?
问答我有一个项目,它有一个SharedCode(Java)模块,其次是一个依赖于SharedCode模块的Android(Android库)模块.我想从SharedCode模块发布一个jar工件,从And ...
插件 – Gradle自定义插件的构建抛出“无法解析类”
问答我正在尝试构建一个gradle自定义插件,而后者依赖于其他插件.特别是,该插件依赖于com.bmuschko.docker-remote-api插件(这又取决于java库com.github.dock ...
1
如何在使用Android Gradle Experimental插件时指定sourceCompatibility编译选项
问答我目前在我的一个应用程序中使用Android Gradle Experimental插件,我希望能够使用retrolambda库.其中一个要求是指定一些compileOptions.在普通的andro ...
1
Android gradle实验插件路线图
问答在我们的company,我们正在开发一个包含Java和本机部分的Android SDK.我们以AAR格式打包SDK,其中包含所有资源,java类和本机位.根据AAR规范,本机库应放在AAR包内的jni ...
2
android – Gradle maven-publish插件生成没有依赖关系的pom
问答我有一个项目,它有一个SharedCode(Java)模块,其次是一个依赖于SharedCode模块的Android(Android库)模块.我以前一直在build.gradle文件中使用maven插 ...
1
Android Gradle 自定义Task 详解
日志转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/76408024 本文出自[赵彦军的博客] 一:Gradle 是什么 Gradle是一 ...
gradle 自定义插件 下载配置文件
日志1.新建Gradle项目: 2.建立src/main/groovy目录,并添加如下代码: ConfigPlugin.groovy package com.wemall.config import or ...
插件 – 应用gradle自定义jar插件
问答我为gradle创建了一个简单的基于groovy的插件. 在我的gradle.build文件中,我有以下内容: apply plugin: 'groovy' dependencies { compil ...
1
android gradle插件和gradle之间的区别
问答Android Studio 3.2 Canary 5 Build #AI-173.4630681, built on March 3, 2018 JRE: 1.8.0_152-release-113 ...
1
如何使用新的gradle实验插件阻止Android.mk的自动生成
问答我正在尝试使用新的Gradle实验插件构建NDK项目,但似乎Gradle忽略了Android.mk并开始编译所有内容而不关注Android.mk中的内容,我知道新的语法和我阅读以下Experiment ...
1
Android Gradle插件如何处理库中的冲突资源?
问答我有一个依赖于两个Android库的Android应用程序项目.两个Android库指定具有相同资源ID的两个资源.在旧的Ant构建系统中,库的优先级是在project.properties文件中指定 ...
1
Android Instant Run Gradle实验插件
问答我遇到以下问题: file or directory'/Users/rpurohit/Documents/StudioProjects/myapp/app/src/androidTest/manife ...
在创建新项目时,重置android studio的默认gradle和插件是最新的吗?
问答有没有办法重置默认的gradle和插件,而不重置我的所有设置,所以我不会在创建新项目时遇到这些错误? Error: Plugin is too old, please update to a more ...
1
将自定义代码样式xml传递给gradle idea插件
问答有没有办法告诉gradle idea插件在生成项目文件时使用自定义代码样式xml? 我总是可以将xml复制到"〜/ Library / Preferences / IntelliJIdea1 ...
我想在使用Android Eclipse ADT插件的同时自定义构建过程
问答安装ADT插件后,以下构建器对于Android项目处于活动状态: > Android资源管理器 > Android预编译器 > Java Builder > Android P ...
1
使用Android Gradle插件编译时如何添加java编译器选项?
问答我有一个build.gradle文件与依赖关系{classpath'com.android.tools.build:gradle:0.13.3′}并应用插件:'com.android.applicat ...
1
android – Gradle构建无法从自定义maven存储库获取依赖关系
问答我在link之后在BitBucket上创建了一个自定义maven repo.当我尝试使用Gradle在我的android项目中使用依赖项时出现以下错误 Executing tasks: [:app:c ...
2
Android Studio错误:不支持的Android Gradle插件版本(0.9.2)
问答我正在开发一个Android项目几个月,我最近将android studio格式从0.5.2升级到0.8.0.现在我无法通过新的Android Studio打开我的项目.每当我尝试打开项目并且无法打开 ...
1