一、核心概念扫盲
-
JAR
(Java Archive):- 是什么? 一个
.jar
文件,里面打包了编译好的 Java 字节码(.class
文件)和相关的资源文件(如配置文件、图片等)。它是 Java 世界通用的库分发格式。 - Android 局限: 纯
JAR
不能 包含 Android 特有的资源文件(如layout
XML,drawable
图片,AndroidManifest.xml
片段等)。如果你的库只包含纯 Java/Kotlin 代码(没有 Android 资源),或者是一个纯粹的 Java 工具库,那么JAR
就够用了。
- 是什么? 一个
-
AAR
(Android Archive):-
是什么? 一个
.aar
文件,是 Android 特有的库分发格式。它本质是一个 ZIP 压缩包,里面包含:- 编译好的 Java/Kotlin 字节码 (
classes.jar
) - 编译好的资源文件 (
res/
) AndroidManifest.xml
- 库本身可能依赖的其他库信息 (
libs/
目录下的JAR
或AAR
) - 混淆规则文件 (
proguard.txt
) - 其他资源(如
assets/
) - 库的元数据 (
R.txt
)
- 编译好的 Java/Kotlin 字节码 (
-
优势: 完美支持 Android 特有的资源、布局、主题、
Manifest
合并等。这是分发 Android 库(尤其是包含 UI 组件、资源等的库)的推荐格式。
-
-
云端仓库 (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 服务器来存放文件(但功能简陋)。
-
-
maven-publish
插件:- 是什么? Gradle 的一个核心插件。它的作用就是标准化地将你的项目产出(如
aar
,jar
)以及这些产出的元信息(POM 文件)发布到指定的 Maven 仓库(无论是公共的还是私有的) 。它是实现发布功能的关键。
- 是什么? Gradle 的一个核心插件。它的作用就是标准化地将你的项目产出(如
-
POM 文件 (Project Object Model):
-
是什么? 一个 XML 文件(通常是
pom-default.xml
)。它描述了你发布的库的关键信息,相当于库的"身份证"和"说明书",包括:groupId
: 通常用反转域名表示,标识库的组织或项目组(如com.example.mylibrary
)。artifactId
: 库本身的名称(如awesome-widget
)。version
: 库的版本号(如1.0.0
,2.1.5-SNAPSHOT
)。packaging
: 打包类型(aar
或jar
)。dependencies
: 该库自身依赖的其他库(非常重要!这样使用你库的项目才能自动下载这些传递依赖)。
-
为什么重要? Gradle(或其他构建工具)就是通过
groupId
,artifactId
,version
(合称 GAV 坐标 ) 在仓库中唯一定位并下载你的库的。依赖关系也是通过 POM 文件传递的。
-
-
Repository URL: 云端仓库的具体网络地址(如
https://repo.maven.apache.org/maven2/
对应 Maven Central)。
二、发布到云端的原理
-
打包: 你使用 Gradle 构建你的库项目 (
Android Library
模块),最终生成aar
或jar
文件(通常在build/outputs/aar/
或build/libs/
目录)。 -
生成元数据 (POM):
maven-publish
插件会自动分析你的库模块配置(尤其是依赖项),生成描述该库的 POM 文件。 -
配置发布目标: 你在项目的
build.gradle
文件中告诉maven-publish
插件:- 要发布什么? (
aar
或jar
) - 发布到哪里? (指定仓库的 URL)
- 如何验证身份? (如果是私有仓库,需要用户名密码、API Key 或 Token)
- 库的 GAV 坐标是什么? (
groupId
,artifactId
,version
)
- 要发布什么? (
-
执行发布任务: 你运行一个特定的 Gradle 任务(通常是
publish
或publishToMavenLocal
)。这个任务会:- 执行打包(如果还没打包)。
- 生成 POM 文件。
- 将打包好的库文件 (
aar
/jar
) 和 POM 文件一起,按照 Maven 仓库的标准目录结构 (groupId
路径 /artifactId
/version
/ 文件名) 上传到你指定的云端仓库 URL。
-
仓库存储: 云端仓库接收到文件后,将其存储在对应的目录下,并使其可供下载。
三、如何使用:发布端
假设你有一个 Android Studio 项目,里面有一个名为 :mylibrary
的 Android Library 模块,你想把它打包成 aar
发布到云端(以发布到 Maven Central 为例,发布到其他仓库类似,主要是 URL 和认证方式不同)。
-
配置库模块的
build.gradle
(通常是mylibrary/build.gradle.kts
或mylibrary/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 和认证信息换成你们公司内部的即可。
- 发布到 Maven Central 需要先在 Sonatype JIRA 注册账号、申请 Group ID (
-
-
执行发布任务:
-
在 Android Studio 右侧的 Gradle 面板 (View -> Tool Windows -> Gradle) 中找到你的库模块 (
:mylibrary
)。 -
展开
Tasks
->publishing
。 -
双击
publish
(或者publishReleasePublicationToMavenRepository
)。这个任务会执行打包、生成 POM、上传文件到你在repositories
块中配置的所有仓库。 -
或者在终端(Terminal)中进入项目根目录运行:
ruby./gradlew :mylibrary:publish
-
-
验证发布成功:
- 登录到目标仓库的 Web 界面(如 Sonatype Nexus, JFrog Artifactory, GitHub Packages),查找你的
groupId
(com.example
),artifactId
(awesome-widget
),version
(1.0.0
) 是否存在。 - 尝试在另一个项目中按照下面的"使用端"步骤添加依赖,看是否能成功下载和使用。
- 登录到目标仓库的 Web 界面(如 Sonatype Nexus, JFrog Artifactory, GitHub Packages),查找你的
四、如何使用:使用端
现在,假设另一个开发者(或者你自己的另一个项目)想要使用你刚刚发布到云端的 com.example:awesome-widget:1.0.0
库。
-
在使用项目的
build.gradle
(通常是项目根目录的build.gradle.kts
或build.gradle
) 中添加仓库地址:scssbuildscript { 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/repositories
或dependencyResolutionManagement/repositories
(新版本 Gradle 推荐) 中包含了存放你库的那个仓库的 URL。否则 Gradle 找不到你的库。
- 关键: 确保
-
在模块的
build.gradle
(通常是app/build.gradle.kts
或app/build.gradle
) 中添加依赖:scssdependencies { implementation("com.example:awesome-widget:1.0.0") // 使用 GAV 坐标声明依赖 // ... 其他依赖 ... }
-
同步项目 & 使用:
-
点击 Android Studio 工具栏的 Sync Project with Gradle Files 按钮。
-
Gradle 会:
- 根据
implementation("com.example:awesome-widget:1.0.0")
中的 GAV 坐标 (com.example
,awesome-widget
,1.0.0
) 查找依赖。 - 在配置的仓库列表(
mavenCentral()
, 你添加的自定义maven
块)中搜索。 - 在
https://s01.oss.sonatype.org/content/repositories/releases/com/example/awesome-widget/1.0.0/
目录下找到awesome-widget-1.0.0.aar
(或.pom
) 文件。 - 下载
aar
文件和pom
文件。 - 解析
pom
文件,发现这个库依赖了androidx.appcompat:appcompat:1.6.1
。 - 再去仓库下载
appcompat
的aar
和它的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)
-
代码共享与复用:
- 团队内部: 将通用的工具类、网络层封装、基础 UI 组件、业务 SDK 打包成库发布到公司私有仓库,供所有团队项目复用,避免重复造轮子,保证一致性。
- 开源社区: 将优秀的解决方案发布到 Maven Central 或 JitPack,供全球开发者使用(如 Retrofit, Glide, OkHttp)。
-
模块化/组件化开发: 在大型项目中,将 App 拆分成多个独立的库模块 (
aar
)。每个模块可以独立开发、测试、发布版本。主 App 通过依赖这些模块组装而成。这提高了编译速度(增量构建)、可维护性和团队并行开发效率。 -
分发 SDK: 如果你开发了一个提供给第三方 App 使用的 SDK(如支付 SDK、推送 SDK、广告 SDK),将其打包成
aar
发布到云端是最标准的交付方式。第三方只需添加一行依赖即可集成。 -
管理内部依赖版本: 通过私有仓库统一管理公司内部各种库的版本,方便版本升级、回滚和依赖冲突解决。
-
持续集成 (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 开发)中使用其中的招式(类和方法)。