博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Gradle入门系列(五)——Gradle其它模块与Plugin插件
阅读量:6352 次
发布时间:2019-06-22

本文共 7237 字,大约阅读时间需要 24 分钟。

Gradle其它模块

一、Settings类

settings.gradle(对应Settings.java)决定哪些工程需要被gradle处理,占用了整个gradle生命周期的三分之一,即Initialzation初始化阶段。

二、SourceSet类

对默认的文件位置进行修改,从而让gradle知道哪种资源要从哪些文件夹中去查找。

// sourceSets是可以调用多次的android {    sourceSets {        main {            jniLibs.srcDirs = ['libs']        }    }    sourceSets {        main {            res.srcDirs = ['src/main/res',                           'src/main/res-ad',                           'src/main/res-player']        }    }}// sourceSets一般情况下是一次性配置android {    sourceSets {        main {            jniLibs.srcDirs = ['libs']            res.srcDirs = ['src/main/res',                           'src/main/res-ad',                           'src/main/res-player']        }    }}// 使用编程的思想,配置sourceSetsthis.android.sourceSets{    main {        jniLibs.srcDirs = ['libs']        res.srcDirs = ['src/main/res',                       'src/main/res-ad',                       'src/main/res-player']    }}复制代码

Gradle Plugin

一、Gradle插件(Plugin)是什么

Gradle中的Plugin是对完成指定功能的Task封装的体现,只要工程依赖了某个Plugin,就能执行该Plugin中所有的功能,如:使用java插件,就可以打出jar包,使用Android插件,就可以生成apk、aar。

二、自定义Plugin

1、创建插件工程

  1. 在工程目录下创建buildSrc文件夹。
  2. 在buildSrc目录下,创建src文件夹、build.gradle文件。
  3. 在buildSrc/src目录下,再创建main文件夹。
  4. 在buildSrc/src/main目录下,再分别创建groovy、resources文件夹。
  5. 在buildSrc/src/main/resources再创建一个META-INF文件夹,再在META-INF下创建一个gradle-plugins文件夹。
  6. 在build.gradel文件中输入如下脚本:
apply plugin: 'groovy'sourceSets {    main {        groovy {            srcDir 'src/main/groovy'        }        resources {            srcDir 'src/main/resources'        }    }}复制代码

最后,Async一下工程,buildSrc就会被识别出来了,整体目录如图:

2、创建插件类

与java一样,在groovy目录下,创建一个包,再创建一个插件类(如:com.lqr.gradle.study.GradleStudyPlugin),该插件类必须实现Plugin接口。

注意:gradle插件类是.groovy文件,不是.java文件

import org.gradle.api.Pluginimport org.gradle.api.Project/** * 自定义Gradle插件 */class GradleStudyPlugin implements Plugin
{
/** * 插件引入时要执行的方法 * @param project 引入当前插件的project */ @Override void apply(Project project) { println 'hello gradle study plugin. current project name is ' + project.name }}复制代码

3、指定插件入口

在编写完插件类的逻辑之后,需要在META-INF.gradle-plugins目录下创建一个properties文件(建议以插件类包名来命名,如:com.lqr.gradle.study.properties),在该properties中声明插件类,以此来指定插件入口。

该properties文件的名字将作为当前gradle插件被app工程引用的依据。

implementation-class=com.lqr.gradle.study.GradleStudyPlugin// 如果报错 Could not find implementation class 'xxx' 的话,一般是类全路径有问题,默认包不需要写包路径,修改如下即可:// implementation-class=GradleStudyPlugin复制代码

4、使用自定义插件

打开app工程的build.gradle,应用上面的自定义gradle插件,并Async。

apply plugin: 'com.android.application'apply plugin: 'com.lqr.gradle.study'android {  ...}复制代码

可以看到,在gradle的配置阶段,就输出了前面自定义插件的apply方法中的日志。

5、创建扩展属性

插件往往会在gradle脚本中进行参数配置,如在android{}中,可以配置compileSdkVersion等参数,其实本质上,就是在gradle脚本中使用闭包方式创建了一个javaBean,并将其传递到插件中被插件识别读取而已。步骤如下:

1)创建一个实体类,声明成员变量,用于接收gradle中配置的参数。(可以理解为就是javaBean,不过要注意,该文件后缀是.groovy,不是.java)

class ReleaseInfoExtension {
String versionCode String versionName String versionInfo String fileName ReleaseInfoExtension() {} @Override String toString() { return "versionCode = ${versionCode} , versionName = ${versionName} ," + " versionInfo = ${versionInfo} , fileName = ${fileName}" }}复制代码

2)在自定义插件中,对当前project进行扩展。

class GradleStudyPlugin implements Plugin
{
/** * 插件引入时要执行的方法 * @param project 引入当前插件的project */ @Override void apply(Project project) { // 这样就可以在gradle脚本中,通过releaseInfo闭包来完成ReleaseInfoExtension的初始化。 project.extensions.create("releaseInfo", ReleaseInfoExtension) }}复制代码

3)打开在app工程的build.gradle,通过扩展key值命名闭包的方式,就可以配置指定参数了。

apply plugin: 'com.lqr.gradle.study'releaseInfo {    versionCode = '1.0.0'    versionName = '100'    versionInfo = '第一个app信息'    fileName = 'release.xml'}复制代码

4)接收参数,如:

def versionCodeMsg = project.extensions.releaseInfo.versionCode复制代码

6、创建扩展Task

自定义插件无非就是封装一些常用Task,所以,扩展Task才是自定义插件的最重要的一部分。

扩展Task也很简单,继承DefaultTask,编写TaskAction注解方法,下面以 “把app版本信息写入到xml文件中”的task 为例,注释很详细,不多赘述:

import groovy.xml.MarkupBuilderimport org.gradle.api.DefaultTaskimport org.gradle.api.tasks.TaskActionclass ReleaseInfoTask extends DefaultTask {
ReleaseInfoTask() { group 'lqr' // 指定分组 description 'update the release info' // 添加说明信息 } /** * 使用TaskAction注解,可以让方法在gradle的执行阶段去执行。 * doFirst其实就是在外部为@TaskAction的最前面添加执行逻辑。 * 而doLast则是在外部为@TaskAction的最后面添加执行逻辑。 */ @TaskAction void doAction() { updateInfo() } private void updateInfo() { // 获取gradle脚本中配置的参数 def versionCodeMsg = project.extensions.releaseInfo.versionCode def versionNameMsg = project.extensions.releaseInfo.versionName def versionInfoMsg = project.extensions.releaseInfo.versionInfo def fileName = project.extensions.releaseInfo.fileName // 创建xml文件 def file = project.file(fileName) if (file != null && !file.exists()) { file.createNewFile() } // 创建写入xml数据所需要的类。 def sw = new StringWriter(); def xmlBuilder = new MarkupBuilder(sw) // 若xml文件中没有内容,就多创建一个realease节点,并写入xml数据 if (file.text != null && file.text.size() <= 0) { xmlBuilder.releases { release { versionCode(versionCodeMsg) versionName(versionNameMsg) versionInfo(versionInfoMsg) } } file.withWriter { writer -> writer.append(sw.toString()) } } else { // 若xml文件中已经有内容,则在原来的内容上追加。 xmlBuilder.release { versionCode(versionCodeMsg) versionName(versionNameMsg) versionInfo(versionInfoMsg) } def lines = file.readLines() def lengths = lines.size() - 1 file.withWriter { writer -> lines.eachWithIndex { String line, int index -> if (index != lengths) { writer.append(line + '\r\n') } else if (index == lengths) { writer.append(sw.toString() + '\r\n') writer.append(line + '\r\n') } } } } }}复制代码

与创建扩展属性一样,扩展Task也需要在project中创建注入。

/** * 自定义Gradle插件 */class GradleStudyPlugin implements Plugin
{
/** * 插件引入时要执行的方法 * @param project 引入当前插件的project */ @Override void apply(Project project) { // 创建扩展属性 // 这样就可以在gradle脚本中,通过releaseInfo闭包来完成ReleaseInfoExtension的初始化。 project.extensions.create("releaseInfo", ReleaseInfoExtension) // 创建Task project.tasks.create("updateReleaseInfo", ReleaseInfoTask) }}复制代码

再次Async工程之后,就可以在Idea的gradle标签里看到自定义好的Task了。

以上就是自定义gradle插件的核心内容了,但是,这种在工程下直接创建buildSrc目录编写的插件,只能对当前工程可见,所以,如果需要将我们自定义好的grdle插件被其他工程所使用,则需要单独创建一个库工程,并创建如buildSrc目录下所有的文件,最后上传maven仓库即可,这部分可自行百度了解。

三、android插件对gradle扩展

自定义Apk输出位置:

this.afterEvaluate {  this.android.applicationVariants.all { variant ->    def output = variant.outpus.first() // 获取变体输出文件(outputs返回是一个集合,但只有一个元素,即输出apk的file)    def apkName = "app-${variant.baseName}-${variant.versionName}.apk"    output.outputFile = new File(output.outputFile.parent, apkName)  }}复制代码

variant.baseName : baidu-release : baiduRelease

转载地址:http://axmla.baihongyu.com/

你可能感兴趣的文章
C#操作DbConnection类
查看>>
倒计时实现
查看>>
PIE SDK点元素的绘制
查看>>
企业分布式微服务云SpringCloud SpringBoot mybatis (十四)服务注册(consul)
查看>>
elasticsearch无故关闭,Log无报错
查看>>
Java实现动态代理的两种方式
查看>>
Python 程序:基于RabbitMQ实现主机管理
查看>>
道路和航路
查看>>
【Android】升级ADT 22 引发的错误
查看>>
XmlDocument的XPath操作
查看>>
python实战演练(四)工资管理系统
查看>>
MySQL Replication
查看>>
H5 canvas控制坦克移动2
查看>>
单例模式(转)
查看>>
c#的Extension Method功能
查看>>
2019春软工1班——第一次阅读作业
查看>>
三十三、ajaxFileUpload图片上传
查看>>
python学习之操作mysql
查看>>
项目开发中经常提及的那些环境总结
查看>>
应用Mongoose开发MongoDB(3)控制器(controllers)
查看>>