如何发布AAR、JAR等到Maven仓库

一、核心概念扫盲

  1. JAR (Java Archive):

    • 是什么? 一个 .jar 文件,里面打包了编译好的 Java 字节码(.class 文件)和相关的资源文件(如配置文件、图片等)。它是 Java 世界通用的库分发格式。
    • Android 局限:JAR 不能 包含 Android 特有的资源文件(如 layout XML, drawable 图片, AndroidManifest.xml 片段等)。如果你的库只包含纯 Java/Kotlin 代码(没有 Android 资源),或者是一个纯粹的 Java 工具库,那么 JAR 就够用了。
  2. AAR (Android Archive):

    • 是什么? 一个 .aar 文件,是 Android 特有的库分发格式。它本质是一个 ZIP 压缩包,里面包含:

      • 编译好的 Java/Kotlin 字节码 (classes.jar)
      • 编译好的资源文件 (res/)
      • AndroidManifest.xml
      • 库本身可能依赖的其他库信息 (libs/ 目录下的 JARAAR)
      • 混淆规则文件 (proguard.txt)
      • 其他资源(如 assets/
      • 库的元数据 (R.txt)
    • 优势: 完美支持 Android 特有的资源、布局、主题、Manifest 合并等。这是分发 Android 库(尤其是包含 UI 组件、资源等的库)的推荐格式。

  3. 云端仓库 (Remote Repository):

    • 是什么? 想象成一个云端的、集中存放各种库文件 (aar, jar) 和它们描述信息的巨大仓库(或工具箱)。常见的公共云端仓库有:

      • Maven Central: 最老牌、最广泛的 Java/Android 公共仓库。很多知名库都在这里。
      • Google Maven: Google 官方维护,主要存放 AndroidX 库、Play Services 等 Google 官方库。
      • JitPack: 一个非常方便的开源库托管平台,直接关联你的 GitHub 仓库即可发布。
    • 私有仓库: 公司或团队内部使用的仓库,用于共享内部开发的库。常见解决方案:

      • Sonatype Nexus: 功能强大的仓库管理器,支持搭建私有 Maven 仓库。
      • JFrog Artifactory: 另一个功能强大的仓库管理器。
      • GitHub Packages: GitHub 提供的包管理服务(包含 Maven 仓库功能)。
      • 简单 HTTP(S) 服务器: 甚至可以自己搭建一个支持目录浏览的 Web 服务器来存放文件(但功能简陋)。
  4. maven-publish 插件:

    • 是什么? Gradle 的一个核心插件。它的作用就是标准化地将你的项目产出(如 aar, jar)以及这些产出的元信息(POM 文件)发布到指定的 Maven 仓库(无论是公共的还是私有的) 。它是实现发布功能的关键。
  5. POM 文件 (Project Object Model):

    • 是什么? 一个 XML 文件(通常是 pom-default.xml)。它描述了你发布的库的关键信息,相当于库的"身份证"和"说明书",包括:

      • groupId: 通常用反转域名表示,标识库的组织或项目组(如 com.example.mylibrary)。
      • artifactId: 库本身的名称(如 awesome-widget)。
      • version: 库的版本号(如 1.0.0, 2.1.5-SNAPSHOT)。
      • packaging: 打包类型(aarjar)。
      • dependencies: 该库自身依赖的其他库(非常重要!这样使用你库的项目才能自动下载这些传递依赖)。
    • 为什么重要? Gradle(或其他构建工具)就是通过 groupId, artifactId, version (合称 GAV 坐标 ) 在仓库中唯一定位并下载你的库的。依赖关系也是通过 POM 文件传递的。

  6. Repository URL: 云端仓库的具体网络地址(如 https://repo.maven.apache.org/maven2/ 对应 Maven Central)。

二、发布到云端的原理

  1. 打包: 你使用 Gradle 构建你的库项目 (Android Library 模块),最终生成 aarjar 文件(通常在 build/outputs/aar/build/libs/ 目录)。

  2. 生成元数据 (POM): maven-publish 插件会自动分析你的库模块配置(尤其是依赖项),生成描述该库的 POM 文件。

  3. 配置发布目标: 你在项目的 build.gradle 文件中告诉 maven-publish 插件:

    • 要发布什么? (aarjar)
    • 发布到哪里? (指定仓库的 URL)
    • 如何验证身份? (如果是私有仓库,需要用户名密码、API Key 或 Token)
    • 库的 GAV 坐标是什么? (groupId, artifactId, version)
  4. 执行发布任务: 你运行一个特定的 Gradle 任务(通常是 publishpublishToMavenLocal)。这个任务会:

    • 执行打包(如果还没打包)。
    • 生成 POM 文件。
    • 将打包好的库文件 (aar/jar) 和 POM 文件一起,按照 Maven 仓库的标准目录结构 (groupId 路径 / artifactId / version / 文件名) 上传到你指定的云端仓库 URL。
  5. 仓库存储: 云端仓库接收到文件后,将其存储在对应的目录下,并使其可供下载。

三、如何使用:发布端

假设你有一个 Android Studio 项目,里面有一个名为 :mylibrary 的 Android Library 模块,你想把它打包成 aar 发布到云端(以发布到 Maven Central 为例,发布到其他仓库类似,主要是 URL 和认证方式不同)。

  1. 配置库模块的 build.gradle (通常是 mylibrary/build.gradle.ktsmylibrary/build.gradle):

    dart 复制代码
    // 1. 应用必要的插件
    plugins {
        id("com.android.library") // Android 库插件
        id("maven-publish") // 核心发布插件
    }
    
    android {
        // ... 你的 Android 配置 (compileSdk, namespace, defaultConfig, buildTypes 等) ...
        // 可选但推荐:为发布构建类型配置
        publishing {
            singleVariant('release') {
            // 发布 release 变体
            // withSourcesJar() // 可选:同时发布包含源码的 JAR
            // withJavadocJar() // 可选:同时发布包含文档的 JAR (需要配置好 Javadoc)
        }
    }
    }
    
    dependencies {
        // ... 你的库依赖 ...
        implementation("androidx.appcompat:appcompat:1.6.1")
    }
    
    // 2. 配置发布
    afterEvaluate { // 确保 Android 配置已完成
        publishing {
            publications {
                create<MavenPublication>("release") { // 创建一个叫 "release" 的发布项
                    // 指定要发布的是这个 Android 库模块的 Release 构建变体产生的 AAR
                    from(components["release"])
    
                    // 3. 设置库的 GAV 坐标 (必须!)
                    groupId = "com.example" // 你的组织/项目组标识
                    artifactId = "awesome-widget" // 你的库名称
                    version = "1.0.0" // 版本号
    
                    // 4. (可选) 可以在这里添加额外的 POM 信息,如描述、开发者信息、许可证、SCM 链接等
                    pom {
                        name.set("Awesome Widget Library")
                        description.set("A library providing amazing widgets for Android apps.")
                        url.set("https://github.com/yourusername/awesome-widget")
                        licenses {
                            license {
                                name.set("The Apache License, Version 2.0")
                                url.set("https://www.apache.org/licenses/LICENSE-2.0.txt")
                            }
                        }
                        developers {
                            developer {
                                id.set("yourusername")
                                name.set("Your Name")
                                email.set("[email protected]")
                            }
                        }
                        //项目源代码管理(Source Control Management)信息的配置块
                        scm {
                            connection.set("scm:git:git://github.com/yourusername/awesome-widget.git")
                            developerConnection.set("scm:git:ssh://github.com:yourusername/awesome-widget.git")
                            url.set("https://github.com/yourusername/awesome-widget")
                        }
                    }
                }
            }
            // 5. 配置要发布到的仓库
            repositories {
                maven {
                    // Maven Central 的发布仓库 URL (注意是 release 仓库,不是浏览的仓库)
                    url = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/")
                    // 认证信息 (需要在 Sonatype JIRA 注册账号并申请项目)
                    credentials {
                        username = project.findProperty("ossrhUsername") as String? ?: ""
                        password = project.findProperty("ossrhPassword") as String? ?: ""
                    }
                }
                // 如果要发布到多个仓库,可以在这里添加多个 `maven { ... }` 配置块
            }
        }
    }
    • 重要提示:

      • 发布到 Maven Central 需要先在 Sonatype JIRA 注册账号、申请 Group ID (com.example)、创建工单并通过审核。过程较繁琐。
      • 用户名密码不要 硬编码在脚本里!通常放在项目的 gradle.properties 文件(不提交到版本控制)或环境变量中。脚本里通过 project.findProperty("ossrhUsername") 读取。
      • 对于 JitPack,配置更简单(通常只需 GitHub 仓库),不需要在库项目中写 publishing 配置,JitPack 会自动构建。
      • 对于私有 Nexus/Artifactory,URL 和认证信息换成你们公司内部的即可。
  2. 执行发布任务:

    • 在 Android Studio 右侧的 Gradle 面板 (View -> Tool Windows -> Gradle) 中找到你的库模块 (:mylibrary)。

    • 展开 Tasks -> publishing

    • 双击 publish (或者 publishReleasePublicationToMavenRepository)。这个任务会执行打包、生成 POM、上传文件到你在 repositories 块中配置的所有仓库。

    • 或者在终端(Terminal)中进入项目根目录运行:

      ruby 复制代码
      ./gradlew :mylibrary:publish
  3. 验证发布成功:

    • 登录到目标仓库的 Web 界面(如 Sonatype Nexus, JFrog Artifactory, GitHub Packages),查找你的 groupId (com.example), artifactId (awesome-widget), version (1.0.0) 是否存在。
    • 尝试在另一个项目中按照下面的"使用端"步骤添加依赖,看是否能成功下载和使用。

四、如何使用:使用端

现在,假设另一个开发者(或者你自己的另一个项目)想要使用你刚刚发布到云端的 com.example:awesome-widget:1.0.0 库。

  1. 在使用项目的 build.gradle (通常是项目根目录的 build.gradle.ktsbuild.gradle) 中添加仓库地址:

    scss 复制代码
    buildscript {
        repositories {
            google()
            mavenCentral() // 如果你的库发布到了 Maven Central
            // 如果你的库发布到了 Google Maven, 通常已有
            // 如果你的库发布到了其他仓库 (如私有 Nexus, JitPack),必须在这里添加!
            maven {
                url = uri("https://s01.oss.sonatype.org/content/repositories/releases/") // Maven Central 发布后同步到的公共浏览地址
                // 或者私有仓库地址: url = uri("https://your.nexus.server/repository/maven-releases/")
                // 如果是需要认证的私有仓库,可能需要在这里配置 credentials { ... }
            }
            maven { url = uri("https://jitpack.io") } // 如果使用 JitPack
        }
        dependencies {
            classpath("com.android.tools.build:gradle:8.3.1") // 或其他版本
            // ... 其他 classpath 依赖 ...
        }
    }
    
    allprojects {
        repositories {
            google()
            mavenCentral() // 重要!标准库来源
            // 同样,需要添加包含你库的特定仓库
            maven {
                url = uri("https://s01.oss.sonatype.org/content/repositories/releases/")
                // 或私有仓库地址
            }
            maven { url = uri("https://jitpack.io") }
        }
    }
    • 关键: 确保 allprojects/repositoriesdependencyResolutionManagement/repositories (新版本 Gradle 推荐) 中包含了存放你库的那个仓库的 URL。否则 Gradle 找不到你的库。
  2. 在模块的 build.gradle (通常是 app/build.gradle.ktsapp/build.gradle) 中添加依赖:

    scss 复制代码
    dependencies {
        implementation("com.example:awesome-widget:1.0.0") // 使用 GAV 坐标声明依赖
        // ... 其他依赖 ...
    }
  3. 同步项目 & 使用:

    • 点击 Android Studio 工具栏的 Sync Project with Gradle Files 按钮。

    • Gradle 会:

      1. 根据 implementation("com.example:awesome-widget:1.0.0") 中的 GAV 坐标 (com.example, awesome-widget, 1.0.0) 查找依赖。
      2. 在配置的仓库列表(mavenCentral(), 你添加的自定义 maven 块)中搜索。
      3. https://s01.oss.sonatype.org/content/repositories/releases/com/example/awesome-widget/1.0.0/ 目录下找到 awesome-widget-1.0.0.aar (或 .pom) 文件。
      4. 下载 aar 文件和 pom 文件。
      5. 解析 pom 文件,发现这个库依赖了 androidx.appcompat:appcompat:1.6.1
      6. 再去仓库下载 appcompataar 和它的 pom 文件(递归处理传递依赖)。
    • 同步成功后,你就可以在你的 Java/Kotlin 代码中 import 你库中的类,在 XML 布局中使用你库中的自定义 View 了。

五、关键指令

  • 发布相关:

    • ./gradlew publish: 执行项目中所有配置好的 publishing 发布任务,上传到所有配置的远程仓库。
    • ./gradlew publishToMavenLocal: 将库发布到本地 Maven 仓库 (通常是 ~/.m2/repository/)。这是测试发布效果 非常方便的方式!在另一个本地项目中,只需在 repositories 中添加 mavenLocal() 就可以优先使用本地发布的版本进行测试,而不用先上传到远程。确认无误后再发布到远程云端。
    • ./gradlew :moduleName:publish...: 指定发布特定模块的任务(如 :mylibrary:publish)。
  • 清理相关:

    • ./gradlew clean: 清理项目的构建输出(build/ 目录)。
    • ./gradlew :moduleName:clean: 清理特定模块的构建输出。
  • 构建相关:

    • ./gradlew :moduleName:assembleRelease: 构建库模块的 Release 版本 AAR(通常在 build/outputs/aar/)。发布插件内部会调用这个任务。

六、使用场景 (Use Cases)

  1. 代码共享与复用:

    • 团队内部: 将通用的工具类、网络层封装、基础 UI 组件、业务 SDK 打包成库发布到公司私有仓库,供所有团队项目复用,避免重复造轮子,保证一致性。
    • 开源社区: 将优秀的解决方案发布到 Maven Central 或 JitPack,供全球开发者使用(如 Retrofit, Glide, OkHttp)。
  2. 模块化/组件化开发: 在大型项目中,将 App 拆分成多个独立的库模块 (aar)。每个模块可以独立开发、测试、发布版本。主 App 通过依赖这些模块组装而成。这提高了编译速度(增量构建)、可维护性和团队并行开发效率。

  3. 分发 SDK: 如果你开发了一个提供给第三方 App 使用的 SDK(如支付 SDK、推送 SDK、广告 SDK),将其打包成 aar 发布到云端是最标准的交付方式。第三方只需添加一行依赖即可集成。

  4. 管理内部依赖版本: 通过私有仓库统一管理公司内部各种库的版本,方便版本升级、回滚和依赖冲突解决。

  5. 持续集成 (CI): 在 CI 服务器(如 Jenkins, GitHub Actions)上,可以自动化执行 publish 任务,每当库代码有新的合并或打 Tag 时,自动发布新版本到仓库。

总结

  • 做什么? 把写好的 Android 库 (Android Library 模块) 打包成 aar (或纯 Java 库打包成 jar),连同它的描述文件 (POM) 一起上传到一个网络可达的仓库服务器。

  • 为什么? 方便自己、团队或全世界其他地方的项目,像使用标准库一样,通过一行 implementation 依赖声明就能使用你的库。

  • 怎么做?

    • 发布端:maven-publish 插件配置 GAV 坐标和仓库地址/认证 -> 运行 publish Gradle 任务。
    • 使用端:build.gradle 中添加你的仓库地址 -> 用 implementation("group:artifact:version") 声明依赖 -> 同步 -> 写代码使用。
  • 核心概念: aar, jar, Maven 仓库 (Maven Central, Google Maven, 私有 Nexus/Artifactory, JitPack), Gradle, maven-publish 插件, POM 文件, GAV 坐标 (groupId, artifactId, version), Repository URL。

通俗比喻: 你写好了一本独特的"武功秘籍"(库),把它装订成书(aar/jar),并在书封面写上书名、作者、出版社和版本号(GAV 坐标 + POM 信息)。然后你把这本书寄存在一个大型的、人人都能访问的"云端图书馆"(Maven 仓库)的特定书架(URL + GAV 路径)上。其他练武之人(开发者)只需要知道你的书名、作者和版本号(implementation 语句),告诉他们的"图书管理员"(Gradle)去那个大图书馆找,管理员就能自动找到、借阅(下载)并理解(索引、编译)你的秘籍,让他们在自己的修炼(App 开发)中使用其中的招式(类和方法)。

相关推荐
小赵学鸿蒙27 分钟前
用Uniapp开发鸿蒙项目 五
前端
小lan猫29 分钟前
【实战】 Vue 3、Anything LLM + DeepSeek本地化项目(五)
前端·vue.js
星使bling30 分钟前
基于Baidu JSAPI Three的卫星轨道三维可视化Demo
前端·javascript
Oder_C31 分钟前
自定义指令-优化v-if和v-show上的使用
前端·javascript·vue.js
小赵学鸿蒙32 分钟前
用Uniapp开发鸿蒙项目 八(上)
前端
拾光拾趣录33 分钟前
TypeScript 数组与对象类型定义
前端
小赵学鸿蒙33 分钟前
用Uniapp开发鸿蒙项目 四
前端
程序猿阿伟1 小时前
《深入解析:如何通过CSS集成WebGPU实现高级图形效果》
前端·css
Monster411 小时前
鸿蒙性能引擎:ArkCompiler实战精要
前端
ze_juejin1 小时前
Typescript中的继承示例
前端·typescript