【Android gradle】自定义一个android gradle插件,并发布到私有Artifactory仓库

news2025/1/11 0:54:49

1. 前言

最近工作部分内容涉及到gradle 插件的编写,在粗浅了解和编码之余来简单梳理下编写一个gradle 插件的相关用法。这里编写的插件还是发布到在前面两篇博客中的Artifactory仓库中。一共分为如下几步:

  1. 配置定义gradle插件、上传到 Artifactory仓库的环境;
  2. 配置插件工程模板、编写具体的Task
  3. 发布和应用插件;

2. hello-plugin

2.1 环境准备和配置

创建一个java gradle项目,然后进入配置过程。使用buildScript脚本来配置仓库地址:

buildscript {
    apply from: './setting.gradle'

    repositories {
        mavenLocal()
        maven {
            allowInsecureProtocol true
            url "http://${maven_host}:8082/artifactory/android_group/"
        }
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:3.4.3'
        //http://plugins.gradle.org/plugin/com.jfrog.artifactory
        classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.15.2"
    }
}

其中com.android.tools.build:gradleGoogle推出的构建Android应用程序的插件,而build-info-extractor-gradle这个插件就是前面文章提到过的发布到私有Artifactory仓库的插件。当然,若不使用改仓库可不添加,可以使用maven-publish发布到本地仓库。然后,应用一下对应的插件:

apply plugin: 'java'
apply plugin: 'maven-publish'
apply plugin: 'com.jfrog.artifactory'

同样配置一下依赖的仓库:

repositories {
    contextUrl = "http://${maven_host}:8082/artifactory"   //The base Artifactory URL if not overridden by the publisher/resolver
    publish {
        repository {
            repoKey = 'android_local'
            username = "${admin}"
            password = "${password}"
            maven = true
        }
    }
}

添加一下开发插件所需的依赖:

dependencies {
    implementation gradleApi()
    implementation 'com.android.tools.build:gradle:3.4.3'

}

最后配置一下发布的脚本:

apply plugin: 'maven-publish'

artifactory {
    contextUrl = "http://${maven_host}:8082/artifactory"   //The base Artifactory URL if not overridden by the publisher/resolver
    publish {
        repository {
            repoKey = 'android_local'
            username = "${admin}"
            password = "${password}"
            maven = true
        }
    }
}


publishing {
    publications {
        mengfou(MavenPublication) {
            groupId = 'com.mengfou'
            artifactId = 'hello-plugin-demo'
            version = "1.0.0"

            artifact("$buildDir/libs/${project.getName()}.jar")

            pom.withXml {
                def dependencies = asNode().appendNode("dependencies")
                configurations.implementation.allDependencies.each {
                    if(it.version != null && it.group != null) {
                        def dependency = dependencies.appendNode("dependency")
                        dependency.appendNode("groupId", it.group)
                        dependency.appendNode("artifactId", it.name)
                        dependency.appendNode("version", it.version)
                    }
                }
            }
        }
    }
}

artifactoryPublish {
    dependsOn("clean")
    finalizedBy("assemble")
    contextUrl = "http://${maven_host}:8082/artifactory/"
    publications ('mengfou')                            // mengfou定义在前面

    clientConfig.publisher.repoKey = 'android_local'    //上传到的仓库地址
    clientConfig.publisher.username = "${admin}"		//artifactory 登录的用户名
    clientConfig.publisher.password = "${password}"	    //artifactory 登录的密码
}

同步一下项目可以看见任务中就出现了我们的artifactoryPublish这个任务。
在这里插入图片描述

2.2 配置项目,编写Task

在项目的resources目录下创建META-INF/gradle-plugins目录,然后新建一个自定义的插件名.properties文件,比如:hello-plugin-demo.properties,其值配置为:implementation-class=com.mengfou.plugin.HelloPlugin。该文件也就是我们插件的入口。
在这里插入图片描述
下面正式来编写一个Task(假设该task需要向打包的apk中塞入一个类),比如:

public class HelloTask extends DefaultTask {

    @TaskAction
    public void doAction() {
        System.out.println("================");
    }
}

然后配置一下:

public class HelloPlugin implements Plugin<Project> {

    @Override
    public void apply(Project project) {
        project.getLogger().info("------------------configure----------------------");

        project.afterEvaluate(new Action<Project>() {
            @Override
            public void execute(Project project) {
                AppExtension appExtension = project.getExtensions().getByType(AppExtension.class);
                for (ApplicationVariant applicationVariant : appExtension.getApplicationVariants()) {
                    String variantName = applicationVariant.getName();
                    Task beforeTask = TaskHelper.findTaskByName(project, "compileDebugJavaWithJavac", variantName);
                    HelloTask task = project.getTasks().create(getTaskName(variantName), HelloTask.class);
                    task.dependsOn(beforeTask);
                    List<Task> tasks = TaskHelper.findTaskByName(project, PackageApplication.class, variantName);
                    for (Task systemTask : tasks) {
                        systemTask.dependsOn(task);
                    }
                }
            }
        });
    }

    private String getTaskName(String variantName) {
        variantName = variantName.substring(0, 1).toUpperCase() + variantName.substring(1);
        return "hello" + variantName + "PluginDemo";
    }
}

定义一个帮助类用来查找系统Task

public class TaskHelper {

    public static List<Task> findTaskByName(Project project, Class<? extends Task> clazz, String variantName) {
        TaskCollection<? extends Task> targetTasks = project.getTasks().withType(clazz).matching(task -> {
            return task.getName().toLowerCase().contains(variantName);
        });
        return new ArrayList<>(targetTasks);
    }

    public static Task findTaskByName(Project project, String taskName, String variantName) {
        if(!taskName.contains(variantName)) {
            taskName = taskName.replace(variantName.equalsIgnoreCase("debug") ? "release" : "debug", variantName);
        }
        return project.getTasks().getByName(taskName);
    }
}

2.3 发布和使用插件

只需要找到右边gradle中的artifactoryPublish这个task,双击执行即可。
在这里插入图片描述
最后就是在一个app项目中引用:

// 引入
classpath "com.mengfou:hello-plugin-demo:1.0.3"

// 使用
apply plugin: 'hello-plugin-demo'

同步后可以看见自定义的这两个Task
在这里插入图片描述
为了更加方便知道这个任务是否会被正确执行,可以使用:

gradlew assemRel --console=plain > fa.txt

根据执行结果,可以看见:
在这里插入图片描述
确实该任务得到了执行。

3. 系统task

不可避免的我们需要知道一些系统task,那么如何获取当前项目的所有系统task呢,其实前面我们使用的 --console=plain参数可以做到,但不够简洁。也可以使用:

gradlew :app:tasks --all

4. 附

  1. 【Android Studio Gradle】发布aar到私有Artifactory仓库
  2. 【Android Studio Gradle】使用Artifactory构建本地仓库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/75350.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于单片机的加热炉炉温控制系统设计

目 录 摘 要 I Abstract II 第1章 绪论 1 1.1课题背景及意义 1 1.2发展现状 2 1.3研究主要内容 3 第2章 加热炉炉温控制系统总体方案设计 4 2.1总体方案的确定 4 2.2加热炉炉温控制系统组成 5 第3章 加热炉炉温控制系统技术和算法介绍 6 3.1 AT89C51简介 6 3.1.1单片机的引脚介…

Crossover2023mac苹果电脑系统上运行Windows程序虚拟机工具模拟器

CrossOver是一款可以让Mac和Linux系统中正常运行Windows软件的应用程序。它不像虚拟机一样需要安装Windows系统之后才可以安装Windows的应用程序&#xff0c;这一方式给大多数用户带来了方便。通过CrossOver实现跨平台的文件复制粘贴&#xff0c;使Mac/Linux系统与Windows应用良…

海康视频回放,rtsp视频接口转换成.m3u8格式文件

通过海康接口返回的rtsp视频接口&#xff0c;转换成.m3u8格式文件&#xff0c;逻辑如下 1、采用ffmpeg实时转化rtsp链接视频&#xff0c;转化为m3u8&#xff0c;存放服务器固定地址 2、采用nginx代理视频成.m3u8视频 3、采用tokenredis方式处理视频播放和删除过程&#xff0…

太好玩了,我用 Python 做了一个 ChatGPT 机器人

大家好&#xff0c;我是早起。 毫无疑问&#xff0c;ChatGPT 已经是当下编程圈最火的话题之一&#xff0c;它不仅能够回答各类问题&#xff0c;甚至还能执行代码&#xff01; 或者是变成一只猫 因为它实在是太好玩&#xff0c;我使用Python将ChatGPT改造&#xff0c;可以实现在…

亚马逊黑五哑火,中国跨境电商高歌猛进!

黑五作为一个类似于中国双11的全球性购物狂欢节&#xff0c;在11月的最后一周拉开帷幕&#xff0c;据有关业内人士称&#xff0c;作为拥有众多全球站的亚马逊电子商务平台在此次黑色星期五的促销狂欢节中表现似乎稍显停滞&#xff0c;其作为电商领域的龙头企业&#xff0c;没能…

数据结构基础--图

一、图的基本概念 1.图的定义 图是由顶点集合V和边集合E组成的&#xff0c;记为G(G,V)。图可以只有点没有边&#xff0c;但不能只有边没有点。边&#xff1a;用&#xff08;x&#xff0c;y&#xff09;表示为xy之间的一条无向边&#xff1b;用<x,y>表示xy之间的一条有向…

大数据开发适合哪类人群?

有不少应届大学毕业生和0基础人群选择学大数据&#xff0c;但是要选择零基础的大数据培训班&#xff0c;从Java基础开始学习&#xff0c;由浅入深掌握离线数据分析、实时数据分析和内存数据计算等重要内容。 应届大学生缺乏工作经验和技能&#xff0c;对未来没有明确的规划&am…

VTK- PointLocator

欢迎大家加入VTK社区雪易VTK社区-CSDN社区云 小结&#xff1a;本博文主要针对VTK中的PointLocator的分类及各接口的用途进行讲解&#xff0c;PointLocator主要用途为点的位置计算&#xff0c;希望能为各位小伙伴有所帮助。 vtk中关于Locator的关系图 目录 vtkLocator vtkAbs…

软件测试基础理论体系学习4-单元测试的目的?概念是什么?过程是什么?

4-单元测试的目的&#xff1f;概念是什么&#xff1f;过程是什么&#xff1f;1 单元测试目的1.1 单元测试的错误认识1.2 单元测试的重要性1.2.1 时间方面1.2.2 测试效果1.2.3 测试成本1.2.4 产品质量1.3 单元测试的优点1.3.1 它是一种验证行为1.3.2 它是一种设计行为1.3.3 它是…

CPU是什么

CPU&#xff08;Central Processing Unit&#xff09;是计算机系统的运算和控制核心&#xff0c;是信息处理、程序运行的最终执行单元&#xff0c;相当于系统的“大脑”。当 CPU 过于繁忙&#xff0c;就像“人脑”并发处理过多的事情&#xff0c;会降低做事的效率&#xff0c;严…

Postman安装和运行

下载安装 Postman是一个方便用于构造请求的软件.可以以简单的方式来构造请求. 要下载软件,还是同样的话,要去官网下载.这里我们直接将官网地址放在这里. https://www.postman.com/downloads/ 进入官网以后,点击windows 64-bit(图中圈起来的部分)即可下载. 下载好以后双击安…

java小技能:JWT认证实现

文章目录 引言I. 预备知识1.1 关键字去空格处理II token组成2.1 头部(Header)2.2 有效载荷(Playload)2.3 签名(Signature)2.4 代码实现:生成tokenIII 验证token3.1 网关验证token3.2 使用拦截器验证token引言 认证流程 I. 预备知识 1.1 关键字去空格处理

前端复制粘贴方式上传图片

最近在做一个论坛的项目&#xff0c;发布评论的时候&#xff0c;很多时候会用到截图上传的功能&#xff0c;通过微信截图&#xff0c;QQ截图&#xff0c;直接将截取的图片通过Ctrlv 复制到输入框里&#xff0c;自动上传将图片渲染到页面上&#xff0c;今天就来实现一个这样的功…

BOS金蝶云星空:表单插件设置单据体背景色

一.效果图&#xff1a; 备注&#xff1a;只适用于只读列 二.代码案例&#xff1a; 自定义单据提附加背景色方法&#xff1a; /// /// 设置单据体背景颜色 /// /// 实体 /// 行 /// 字段 /// 颜色代码 private void SetEntityBackgoundColor(string entityKey, int row, st…

【面试题】大厂面试题分享:如何让(a===1a===2a===3)的值为true?

大厂面试题分享 面试题库 前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 当我第一次看到这一题目的时候&#xff0c;我是比较震惊的&#xff0c;分析了下很不合我们编程的常理&#xff0c;并认为不大可能&#…

面试官:断网了,还能 ping 通 127.0.0.1 吗?

你女神爱不爱你&#xff0c;你问她&#xff0c;她可能不会告诉你。 ‍ 但网通不通&#xff0c;你 ping 一下就知道了。 可能看到标题&#xff0c;你就知道答案了&#xff0c;但是你了解背后的原因吗&#xff1f; 那如果把 127.0.0.1 换成 0.0.0.0 或 localhost 会怎么样呢&…

Win10用命令行编译带有cuda的opencv

0. 环境 笔记本win10 NVIDIA GeForce GTX 1660 Ti 1. 准备x64 Native Tools Command Prompt 1.1 准备Visual Studio Installer 需要安装visual studio 2019 1.2 安装工作负荷 为了安装x64 Native Tools Command Prompt&#xff0c;勾上使用C的桌面开发 安装完毕后&#xf…

Latent Class Modeling lca

潜类别模型&#xff08;Latent Class Modeling&#xff09; 潜在类别分析&#xff08;LCA&#xff09;数据分析流程&#xff08;详细版&#xff09; - 简书 (jianshu.com) R数据分析&#xff1a;用R语言做潜类别分析LCA - 知乎 (zhihu.com) About Latent Class Modeling -…

Postman(六): postman定义公共函数

Postman(11): postman定义公共函数 postman定义公共函数 在postman中&#xff0c;如下面的代码&#xff1a; 1、返回元素是否与预期值一致 var assertEqual(name,actual,expected)>{tests[${name}&#xff1a;实际结果&#xff1a; ${actual} &#xff0c; 期望结果&…

PDF转Excel怎么转?这些方法值得收藏

在我们的工作生活中&#xff0c;避免不了Excel表格的使用&#xff0c;当我们遇到想要将PDF文件中的信息转换制作成表格的时候&#xff0c;要怎么做呢&#xff1f;毕竟&#xff0c;PDF文件是一个不易编辑的格式&#xff0c;我们想复制其中的内容就较为的麻烦。一般这种时候&…