/GradlePluginDemo

Gradle插件

Primary LanguageJavaApache License 2.0Apache-2.0

GradlePluginDemo

Android Gradle插件开发-插件搭建

第一 构建基础插件。

Gradle插件需要开发者具备Groovy语法的基础,要不然很难懂插件的原理跟写插件的脚本,如果照葫芦画瓢写出来一个插件,到最后还是一脸懵逼什么都不懂。这里用Module单独开发插件。

第一步: 新建一个moduledemo使用的module的名字为gradleplugin,然后删除src目录下面的除main目录的其它的文件夹。删除后如图:

图一

第二步: 接着删除main文件夹下面的所有文件夹以及文件,删除后如图:

第三步: 删除build.gradle里面的文件内容,并且引入groovy插件,因为我们需要用到groovy语法,如图所示:

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

dependencies {
    compile gradleApi()
    compile localGroovy()
    //这里面你想用什么就去引入什么
    compile 'com.android.tools.build:gradle:3.0.0'
}

repositories {
    jcenter()
}

第四步:main文件下面建立groovy文件夹,一定不要拼写错误哦。然后在main/groovy里面创建groovy文件用来写脚本,注意文件的后缀要是***.groovy***。

第五步: 写插件,我们需要实现Plugin接口泛型为Project(Gradle的Project),然后复写apply方法,在apply方法里面写脚本。

第六步:main目录下建立resources/META-INF/gradle-plugins文件夹,然后建立com.demo.plugin.properties文件,文件的名称随意定义,之后引入插件的时候会根据该名称引入,如apply plugin: 'com.demo.plugin',文件内容为key = valuekey写死为implementation-classvalue为你写定义的那个groovy文件的路径,一般是选择你定义好的package+文件名

第七步: 打包发到本地的maven仓库里面。先在该modulebuild.gradle文件里面写下仓库的配置文件。

uploadArchives {
    repositories.mavenDeployer {
        repository(url: uri('../gradleplugin/src/main/repertory'))
        pom.groupId = 'com.wang'
        pom.artifactId = 'demo-plugin'
        pom.version = "1.0.0"
    }
}

然后同步一下,之后去点击Android Studio 右侧的Gradle 。如图所示:

点击 uploadArchives 之后开始执行task结束之后就会再我们定义的仓库的路径中找到如下文件:

这样我们的本地仓库创建完毕,可以再根目录的build.gradle里面引用了。

第八步: 引用插件。在根目录的build.gradle里面配置我们本地仓库的maven地址以及classpath

之后再需要用到插件的地方引用*apply plugin: 'com.demo.plugin'*就可以,这里的插件名称就是我们定义的那个

com.demo.plugin.properties文件的前缀。引入之后build一下会在Gradle Console里面看到我们写的插件脚本的打印信息。

到此我们完成了一个简单Gradle插件,并发到了我们本地的maven仓库.

第二:自定义插件像applicatipn插件一样接受属性传值。

通过以上的学习我们搭建起来了自定义插件,也让插件正常运行起来,那么我们如何才能想application插件那种接收属性值呢?以下的demo是接着上面的写下去的。先来看下Android applicatipn插件定义的属性:

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "plugin.gradle.com.gradleplugindemo"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

那么自定义的插件再完成某些需求的时候也需要接受参数。接下来看如何像application一样去接收参数。

1.属性直接赋值.

pluginVersion 26
pluginName "pluginOne"
//我们要接收使用插件的build.gradle文件里面写的这些属性

第一步::首先先创建一个接收自定义属性的类。可以再跟我们的插件同一个包里面直接创建一个groovy文件,记得一定要是*.groovy后缀啊。这里呢我们建立一个CusProperties*的文件.

package com.plugin

class CusProperties {
    def pluginVersion
    def pluginName

    @Override
    String toString() {
        return "pluginVersion is  " + pluginVersion +"     pluginName  is   " +pluginName
    }
}

第二步:将我们的自定属性添加到目标对象上,这是官方解释.先看下面的代码:

project.extensions.create("cusProperties",CusProperties)

代码不多但是很陌生吧,碰到不熟悉的类方法属性呢我们最好先去看下API的解释,这里project.extensions调用的是Project内部的ExtensionContainer类,这个类的作用就是Allows adding 'namespaced' DSL extensions to a target object,也就是将自定义的命名空间添加到调用者project里面。然后调用ExtensionContainercreate方法,该方法有好几个重载的方法,具体请看api,调用create方法就可以把我们自定义的类跟我们build.gradle里面的定义的属性相关联了。也就是直接赋值给我们自定义的类里面,先看下完整的代码吧:

package com.plugin

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


class DemoPlugin implements Plugin<Project>{
    @Override
    void apply(Project project) {
        CusProperties cus = project.extensions.create("cusProperties",CusProperties)
        project.afterEvaluate {
            println("=================   "+cus.toString())
        }
    }
}

这是插件代码书写完成的样子:

第三步 :当我们每次改变插件文件的内容的时候记得要重新打包进本地的仓库中。

点击uploadArchives重新把插件里面的代码打包到本地的仓库,要不然项目引用的插件还是之前的代码。

第三步:再引用该插件的地方去写自定义的属性。

第四步:重新build一下我们就就会看到我们再插件里面打印的信息。

这就说明我们的接收到了自定义命名空间的值。

注意点:

1.我们的插件是在*apply plugin: 'com.demo.plugin'*的时候就会执行apply方法里面的代码,那么自定义属性都是定义再引入插件之后,那么我们如果不采取措施的话是接收不到属性值的。请看下面的代码:

class DemoPlugin implements Plugin<Project>{
    @Override
    void apply(Project project) {
        CusProperties cus = project.extensions.create("cusProperties",CusProperties)
        println("=================   打印1  "+cus.toString())
        //该方法是Project建立好任务的有向图之后再执行,一般需要再某个系统任务之后或者之前做一些事情的时候一定要在这个方法里面去写
        project.afterEvaluate {
            println("=================   打印2  "+cus.toString())
        }
    }
}

结果:
    =================   打印1  pluginVersion is  null     pluginName  is   null
=================   打印2  pluginVersion is  26     pluginName  is   pluginOne

一定要让我们定义的自定义属性代码走过之后再去获取值。

2.就是当我们的插件文件有改动的时候一定要记得重新生成本地仓库。当升级插件的版本的时候要把之前的依赖都注释掉再生成新版本的仓库。