使用 AAR 和源 JAR 将 Android 库发布到 Maven

2023-11-27

有人可以给我一个关于如何使用的提示吗maven-publishGradle 插件发布com.android.library带有 AAR 和源 jar 的项目/模块?我可以用旧的来做到这一点maven插件 - 但我想使用新的maven-publish plugin.


With Android Gradle 插件 7.1现在执行此操作非常简单,无需任何复杂的脚本。 AGP 现在还可以处理创建源代码和 javadocs jar。

您不需要任何单独的脚本,只需将所有内容写入您的build.gradle你的模块的文件:

plugins {
    ...
    id 'maven-publish'
}
android {
    ...
    publishing {
        singleVariant("release") {
            // if you don't want sources/javadoc, remove these lines
            withSourcesJar()
            withJavadocJar()
        }
    }
}
afterEvaluate {
    publishing {
        publications {
            release(MavenPublication) {
                from components.release
                groupId 'com.example'
                artifactId 'mylibrary'
                version '1.0.0'
            }
        }
    }
}

参见官方文档:https://developer.android.com/build/publish-library


旧答案

自 Android Studio 3.6 发布以来,Android Gradle 插件 3.6.0(及更高版本)中实现了对构建 AAR(甚至 APK 和 AAB)的支持。

我们不再需要处理 XML 依赖关系并自行填充。

这是我更新的 Android Studio 3.6.0 要点:https://gist.github.com/Robyer/a6578e60127418b380ca133a1291f017

要点代码:

apply plugin: 'maven-publish'

task androidJavadocs(type: Javadoc) {
    source = android.sourceSets.main.java.srcDirs
    classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
    android.libraryVariants.all { variant ->
        if (variant.name == 'release') {
            owner.classpath += variant.javaCompileProvider.get().classpath
        }
    }
    exclude '**/R.html', '**/R.*.html', '**/index.html'
}

task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
    archiveClassifier.set('javadoc')
    from androidJavadocs.destinationDir
}

task androidSourcesJar(type: Jar) {
    archiveClassifier.set('sources')
    from android.sourceSets.main.java.srcDirs
}

// Because the components are created only during the afterEvaluate phase, you must
// configure your publications using the afterEvaluate() lifecycle method.
afterEvaluate {
    publishing {
        publications {
            // Creates a Maven publication called "release".
            release(MavenPublication) {
                // Applies the component for the release build variant.
                from components.release

                // Adds javadocs and sources as separate jars.
                artifact androidJavadocsJar
                artifact androidSourcesJar

                // You can customize attributes of the publication here or in module's build.gradle file (if you save this as script and include it build.gradle file, then you can just replicate this whole block there only with changed fields).
                //groupId = 'com.example'
                //artifactId = 'custom-artifact'
                version = android.defaultConfig.versionName // or just '1.0'
            }
        }
    }
}

原答案:

这是我根据其他答案改进的解决方案。

Gist: https://gist.github.com/Robyer/a6578e60127418b380ca133a1291f017

其他答案的更改:

  • Changed classifier- 一定是"sources" (not "source")
  • Handles dependencies
    • 还支持@aar and transitive: false。在这种情况下,我们在 POM 中设置排除来忽略此依赖项的所有传递依赖项。

    • 还支持依赖项的自定义排除规则,例如:

        compile('com.example:something:1.0', {
            exclude group: 'com.exclude.this', module: 'some-module'
        })
      
  • 不需要手动指定工件路径。

apply plugin: 'maven-publish'

task androidJavadocs(type: Javadoc) {
    source = android.sourceSets.main.java.srcDirs
    classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
    android.libraryVariants.all { variant ->
        if (variant.name == 'release') {
            owner.classpath += variant.javaCompile.classpath
        }
    }
    exclude '**/R.html', '**/R.*.html', '**/index.html'
}

task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
    classifier = 'javadoc'
    from androidJavadocs.destinationDir
}

task androidSourcesJar(type: Jar) {
    classifier = 'sources'
    from android.sourceSets.main.java.srcDirs
}

project.afterEvaluate {
    publishing {
        publications {
            maven(MavenPublication) {
                //groupId 'cz.example'
                //artifactId 'custom-artifact'
                //version = android.defaultConfig.versionName
    
                artifact bundleReleaseAar
                artifact androidJavadocsJar
                artifact androidSourcesJar
    
                pom.withXml {
                    final dependenciesNode = asNode().appendNode('dependencies')
    
                    ext.addDependency = { Dependency dep, String scope ->
                        if (dep.group == null || dep.version == null || dep.name == null || dep.name == "unspecified")
                            return // ignore invalid dependencies
    
                        final dependencyNode = dependenciesNode.appendNode('dependency')
                        dependencyNode.appendNode('groupId', dep.group)
                        dependencyNode.appendNode('artifactId', dep.name)
                        dependencyNode.appendNode('version', dep.version)
                        dependencyNode.appendNode('scope', scope)
    
                        if (!dep.transitive) {
                            // If this dependency is transitive, we should force exclude all its dependencies them from the POM
                            final exclusionNode = dependencyNode.appendNode('exclusions').appendNode('exclusion')
                            exclusionNode.appendNode('groupId', '*')
                            exclusionNode.appendNode('artifactId', '*')
                        } else if (!dep.properties.excludeRules.empty) {
                            // Otherwise add specified exclude rules
                            final exclusionNode = dependencyNode.appendNode('exclusions').appendNode('exclusion')
                            dep.properties.excludeRules.each { ExcludeRule rule ->
                                exclusionNode.appendNode('groupId', rule.group ?: '*')
                                exclusionNode.appendNode('artifactId', rule.module ?: '*')
                            }
                        }
                    }
    
                    // List all "compile" dependencies (for old Gradle)
                    configurations.compile.getDependencies().each { dep -> addDependency(dep, "compile") }
                    // List all "api" dependencies (for new Gradle) as "compile" dependencies
                    configurations.api.getDependencies().each { dep -> addDependency(dep, "compile") }
                    // List all "implementation" dependencies (for new Gradle) as "runtime" dependencies
                    configurations.implementation.getDependencies().each { dep -> addDependency(dep, "runtime") }
                }
            }
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 AAR 和源 JAR 将 Android 库发布到 Maven 的相关文章

  • 使用 JSONArray 还是普通数组来存储/读取数据更有效?

    我正在使用一个连接到PHP MySQL返回所有内容的服务器JSON格式 例如 用户列表作为JSONArray of JSONObject 每个对象都包含单个用户的信息 姓名 位置 电话号码等 处理这种格式的信息时 将所有内容保留在其中会更有
  • 如何在 Android 中更改 Drawable 的颜色?

    我正在开发一个 Android 应用程序 并且我有一个从源图像加载的可绘制对象 在此图像上 我想将所有白色像素转换为不同的颜色 例如蓝色 然后缓存生成的 Drawable 对象 以便稍后使用它 举例来说 假设我有一个 20x20 PNG 文
  • 如何使用 gradle 从 3 个子模块构建 1 个 jar

    I have 安卓工作室3 gradle 4 1 梯度工具3 classpath com android tools build gradle 3 0 1 当我有一个模块并使用 gradle 工具 2 时 我使用了 task makeJar
  • 如何在android中显示对话框之外的图像?

    我试图在对话框片段的顶部显示配置文件图像 一半在图像之外 我在下面附加了示例对话框 就像那样 并尝试了旧 Stackoverflow 解决方案中的所有 FrameLayout 协作 但我无法存档此内容 请给我正确的解决方案 谢谢 Updat
  • Android 图表[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在开发一个项目 其中有一些图表 图形 刻度图 烛台图和范围图 但问题是 没有该图表的库 我有烛台图的
  • 当满足条件时,如何以编程方式更改 ImageButton src 目标?

    我有一个学校项目 我正在尝试开发一个手电筒应用程序 对于开 关 ImageButton 我想要 4 个自定义图像 如果手电筒关闭 turn on png 默认 turn on pressing png 按下状态 true 如果手电筒打开 t
  • 为什么反射会减慢Android手机的速度

    我多次读到反射会降低手机性能 这有多真实 例如 在我的例子中 我从 Web 服务获取一些参数 这些参数与我在 Android 应用程序中的类的参数同名 所以我只是使用java字段和反射设置这些参数的值 它似乎并没有降低性能 有人可以向我解释
  • Fragment 问题中的 ExpandableListView

    我正在尝试在片段中实现可扩展列表视图 没有错误出现 当我尝试记录两个的输出时List
  • ADB TCPIP 连接问题

    我有两台 Galaxy S3 其中一个已扎根 另一个则未扎根 因此 当我尝试通过本地网络连接它们时 计算机可以看到已root的计算机 但是正常的就卡在tcpip这一步了 所以 我写 adb tcpip 5555 It says restar
  • Android 中 localTime 和 localDate 的替代类有哪些? [复制]

    这个问题在这里已经有答案了 我想使用从 android API 获得的长值 该值将日期返回为长值 表示为自纪元以来的毫秒数 我需要使用像 isBefore plusDays isAfter 这样的方法 Cursor managedCurso
  • Android -room 持久库 - DAO 调用是异步的,因此如何获取回调?

    从我读到的Room 不允许您在主线程上发出数据库查询 因为可能会导致主线程延迟 所以想象一下我正在尝试更新 UI 主线程上的文本视图 其中一些数据我将如何得到回调 让我给你举个例子 想象一下 我想将我的业务模型数据存储到一个名为 事件 的对
  • 在新的 intel x86 android 模拟器中访问 google api

    我只是尝试在新的 x86 android 模拟器中运行我公司的应用程序 但是我们的应用程序依赖于 google 地图 API 而这在 google 随 android sdk 版本 17 提供的 x86 系统映像中不可用 我的直觉告诉我答案
  • Android蓝牙java.io.IOException:bt套接字已关闭,读取返回:-1

    我正在尝试编写一个代码 仅连接到运行 Android 5 0 KitKat 的设备上的 目前 唯一配对的设备 无论我尝试了多少方法 我仍然会收到此错误 这是我尝试过的最后一个代码 它似乎完成了我看到人们报告为成功的所有事情 有人能指出我做错
  • 如何使用 SharedPreferences 保存多个值?

    我正在开发一个字典应用程序 在我的应用程序中 我假设用户想要保存最喜欢的单词 我决定使用共享首选项保存这些值 我知道 SQLite 和文件更好 但我坚持使用 SharedPreferences 所以继续使用它 下面是我的代码 Overrid
  • 哪个视图最亮?

    在Android中 哪个是轻量级视图 例如 View Textview Edittext 等 在某些情况下 我们需要使用视图来填充区域而不向用户显示视图 同时屏幕加载速度应该很快 您可以使用空间 android widget Space S
  • onTaskRemoved() 在华为和小米设备中没有被调用

    我一直在使用onTaskRemoved 服务中的方法 用于检测应用程序何时通过滑动从设备最近列表中删除 我执行一些日志记录和发生这种情况时需要执行的一些其他操作 它工作完美 然后我在运行Android 6 0的华为设备上检查了这个方法 该方
  • 如何将样式应用于我拥有的所有 TextView? [复制]

    这个问题在这里已经有答案了 可能的重复 设计所有 TextView 或自定义视图 的样式 而不向每个 TextView 添加样式属性 https stackoverflow com questions 6801890 styling all
  • 如何从 Spring Boot 中排除依赖项

    我正在使用 Spring Boot 以下是我的 gradle 文件 buildscript ext springBootVersion 2 0 0 BUILD SNAPSHOT repositories mavenCentral maven
  • ECDH使用Android KeyStore生成私钥

    我正在尝试使用 Android KeyStore Provider 生成的私有文件在 Android 中实现 ECDH public byte ecdh PublicKey otherPubKey throws Exception try
  • 如何访问我的 Android 程序中的联系人

    我正在制作一个短信应用程序 并且想要访问我的 Android 应用程序中的联系人 我想访问联系人 就像他们在实际联系人列表中一样 选择后 我需要返回到我的活动 在其中我可以向该人发送短信 或者是否可以访问存储联系人的数据库 我的代码如下所示

随机推荐

  • 在 Android 中连接 2 个模拟器实例

    我想在2个模拟器中创建一个服务器和一个客户端来写入和读取数据 我为服务器编写代码 public class ServerActivity extends Activity Called when the activity is first
  • 当我们将多维数组传递给函数时,为什么可以省略它的第一维

    当我们将多维数组传递给函数时 为什么可以省略多维数组的第一维 在我的编程课上 我们被告知在将多维数组传递给函数时我们可以省略第一维 例如 a 10 15 20 可以传递为a 15 20 Why 因为数组将衰减为指针并计算数组元素的偏移量 所
  • 如果值在范围内,则合并 2 个数据帧

    我已经为此苦苦挣扎了一段时间 找不到任何方法 所以如果您能提供帮助 我将非常感激 我是编程新手 我的代码可能效率低下 但这是我能想到的最好的 基本上 我有 2 个 csv 文件 fixes csv 和zones csv 它们包含不同的变量并
  • 具有 ContainsTable 的多列和带有全文索引的布尔逻辑

    我有一个非常基本的场景 但我所读到的内容听起来使用 SQL Server 全文目录和索引并不容易 我有两列 名字和姓氏 我想支持对他们的全文搜索 这样如果有人输入 John Smith 则匹配的人both第一个和最后一个首先出现 虽然创建跨
  • 支持传播的 Spring 事务

    我想了解 Spring 事务与传播支持的用途 java 文档提到 如果该方法具有 Transactional propagation Propagation SUPPORTS 从事务内部调用它支持事务 但如果不存在事务 则该方法将以非事务方
  • 使用 DefaultHTTPClient 时如何显示所有 HTTP 标头?

    当使用DefaultHttpClient 从 Apache Commons HTTP 客户端 是否可以在控制台输出中显示完整的请求以进行调试 我的应用程序遇到问题 我觉得调试它的最简单方法是检查由应用程序发送的所有数据DefaultHTTP
  • PostgreSQL 的 random() 函数的质量如何?

    假设我正在创建一个表foo有一个柱子bar这应该是一个非常大的随机整数 CREATE TABLE foo bar bigint DEFAULT round 9223372036854775807 bigint double precisio
  • 如何在Sqlite中删除表与其他表的内连接?

    我的查询 DELETE a FROM TR ContactResultRecord a INNER JOIN TR Case b on a FireStationCode b FireStationCode and a CaseNo b C
  • DocumentFragment 浏览器支持

    今天我偶然发现了 createDocumentFragment 我想知道 DocumentFragment 是否受支持 以及如何在不同的浏览器上支持 特别是 IE 系列 有人知道关于这个主题的任何事情吗 是的 所有现代浏览器 包括 IE6
  • 在 ColdFusion 中使用带命名参数的冒号

    我在录音中看到了这个代码示例 想知道冒号语法的作用 我搜索了文档 但找不到任何相关信息 weather subscribe observer application observers currentConditions 我知道我们可以在
  • 如何在网站中嵌入 LIVE Colab Notebook?

    我想建立一个网站并将其部署到github页面或heroku 我的问题是 是否可以在我将托管的网站中嵌入 LIVE 我可以运行代码 Google Colab 笔记本 我想要这个嵌入式 Colab 笔记本来执行 Spark 代码 Thanks
  • 执行 jenkins sh 管道步骤时权限被拒绝

    我对这种情况有一些麻烦 每次我创建一个新的管道作业 标题为 管道 时 sh即使使用像这样的简单命令 步骤也不起作用ls or pwd它返回此日志 sh 1 var jenkins home workspace pipeline tmp du
  • Java EE 6 CDI 实现之间的差异

    我查看了 JBoss 的 JSR 299 上下文和依赖注入的 Weld 参考实现 我想知道其他 CDI 实现之间的比较 具体来说 我了解 Weld Resin CanDI 由 Caucho 开发 和 Apache OpenWebBeans
  • SQLite 连接未出现在实体数据模型向导中

    我做了什么才到达现在的位置 我安装了该程序集http system data sqlite org index html doc trunk www downloads wiki使用 GAC 和 VS2012 选项 我现在可以连接到现有的
  • 如何封送可变大小的结构数组? C# 和 C++ 互操作帮助

    我有以下 C 结构 struct InnerStruct int A int B struct OuterStruct int numberStructs InnerStruct innerStructs 和一个 C 函数 OuterStr
  • BLAS 中矩阵之间的元素明智乘法?

    我开始在 C 特别是 Intel MKL 中使用 BLAS 函数来创建一些旧 Matlab 代码的更快版本 到目前为止 它运行良好 但我不知道如何对 2 个矩阵 Matlab 中的 A B 执行元素乘法 我知道 gemv 在矩阵和向量之间做
  • 取消所有AsyncTask?

    我有一个用于获取媒体文件拇指的类 这个类似 Loader 的类启动了一个AsyncTask对于每一个ImageView 被称为SomeAdapter getView 任务本身做了很多事情 其中 之一就是调用DiskLruCache 但是当卸
  • 用于检测数据集中太大而无法完全加载到内存中的重复项的算法

    这个问题有最优解吗 描述一种在包含一百万个电话号码的文件中查找重复项的算法 该算法在运行时只有两兆字节的可用内存 这意味着您无法一次将所有电话号码加载到内存中 我的 天真的 解决方案是一个 O n 2 解决方案 它迭代这些值并只加载文件块而
  • 将 log4j.properties 转换为 log4j.xml 的脚本

    我需要使用自定义过滤器 因此我需要将一些长 log4j properties 文件转换为 log4j xml 有人知道有一种工具可以做到这一点 或者愿意贡献一个他们使用过的工具吗 到目前为止 搜索还没有找到这样的工具 我也需要这样做 但找不
  • 使用 AAR 和源 JAR 将 Android 库发布到 Maven

    有人可以给我一个关于如何使用的提示吗maven publishGradle 插件发布com android library带有 AAR 和源 jar 的项目 模块 我可以用旧的来做到这一点maven插件 但我想使用新的maven publi