阅读这个博客,你会知道
Maven 官网 上的介绍:
Apache Maven is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project’s build, reporting and documentation from a central piece of information.
Maven 是一个软件项目管理工具和构建工具,基于 POM 的概念,Maven 可以参与项目的构建过程,还可以通过一些信息生成项目报告和文档。
总结来说,Maven 的功能可以分成三个方面:
优秀的构建工具
通过简单的命令,能够完成清理、编译、测试、打包、部署等一系列过程。同时,不得不提的是,Maven 是跨平台的,无论是在 Windows、还是在 Linux 或 Mac 上,都可以使用同样的命令。
依赖管理工具
项目依赖的第三方的开源类库,都可以通过依赖的方式引入到项目中来。代替了原来需要首先下载第三方 jar,再加入到项目中的方式。从而更好的解决了合作开发中依赖增多、版本不一致、版本冲突、依赖臃肿等问题。
具体是怎么实现的呢?Maven 通过坐标系统准确的定位每一个构件,即通过坐标找到对应的 java 类库。
项目信息管理工具
能够管理项目描述、开发者列表、版本控制系统地址、许可证等一些比较零散的项目信息。除了直接的项目信息,通过 Maven 自动生成的站点,以及一些已有的插件,还能够轻松获得项目文档、测试报告、静态分析报告、源码版本、日志报告等非常具有价值的项目信息。
我们的开发过程中, Maven 是作为一个依赖管理工具的角色,我们把三方库上传到 Maven 的远程仓库中,项目构建的时候,通过 build.gradle 中的配置,去 Maven 仓库中找到对应的库,就开始下载对应的 aar 或 jar,并依赖到项目中。
当搜索上传 aar 到 Maven 仓库
,会看到很多相关博客,其中上传的代码都大同小异,但是目标仓库却有很多种,大概可以分为以下几类:
JCenter
标准的Maven仓库,由 Bintray 公司维护,上传这个仓库,需要注册 Bintray 账号,上传 library 到自己账号下的库地址下,然后同步 JCenter 中央仓库。
JCenter 现在是 Google 官方默认的中央仓库。新项目创建时,RootProject 的 build.gradle 的 repositories
默认已经添加 jcenter()
仓库地址。
Maven Central
同 Jcenter 一样是标准的 Maven 仓库,由 Sonatype 维护。上传这个仓库,需要注册 Sonatype 账号,上传 library 到自己账号下的库地址下,然后同步 Maven Central 中央仓库。
Nexus
Nexus是一个 Maven 仓库管理器,用来搭建私有仓库服务器。公司几乎都会创建一个 Nexus 私有 Maven 仓库,用来存放公司内部的三方库,实现各个模块间的共享。另外好处就是便于管理,节省公网带宽,利用内网下载依赖项速度快。
因为有的童鞋没有私有 Nexus 仓库管理地址,所以我们这里用 jCenter 仓库做演示。
JCenter 的用户资源很多并且十分活跃,而且是 Google 官方默认的中央仓库,如果想开源一个你的项目, 上传到 JCenter 不失为是一个好想法。
上传步骤也很简单,总结来说只有四步:
1.去 Bintray 网站 注册一个账号。Bintray 账号有个人账号和企业账号之分,这里切记,要注册个人号。看下图箭头所指:
2.登录账号 ,点击 Add New Repository
,创建一个存储库,用来托管我们的代码。Name 可以任意,但是请填写 maven
,后面会解释原因,Type 选择 Maven,剩下的是可选项,可以不填。
3.进入刚才创建的 Repository,点击 Add New Package
,创建 Package。Name 任意,Licences 选择 Apache-2.0,Version control 填入版本管理的地址,我填的是测试项目的 GitHub 仓库地址,其他项是选填,可以不填。
此步骤,就是准备好一个要上传的 Android Library Module 就好啦!
这里我新建了一个空的库项目,在其中新建了一个 Java 类和 Activity,用来后面测试这个库好不好使。
测试无所谓,实际开发的话,还请知悉 Android 库项目开发官方文档,里面有给出开发注意事项,要好好听谷爹的话。
Bintray 公司提供了一个 Gradle 插件 gradle-bintray-plugin ,用来将项目上传到 Bintray 和 jCenter。
配置的步骤有很多,对于不太懂 Gradle 的童鞋,例如我,就算是 Copy & Paste 都很心累,而且粘贴复制后代码也不是很美观。
bintray-release 的出现解决了以上问题,我们直接使用 bintray-release 快速配置上传。
我使用的时候,bintray-release 的最新版本是 0.8.0.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.novoda:bintray-release:0.8.0'
}
}
apply plugin: 'com.android.library'
apply plugin: 'com.novoda.bintray-release'//添加
//生成源文件
task sourcesJar(type: Jar) {
from android.sourceSets.main.java.srcDirs
classifier = 'sources'
}
//生成Javadoc文档
task javadoc(type: Javadoc) {
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}
//文档打包成jar
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
//拷贝javadoc文件
task copyDoc(type: Copy) {
from "${buildDir}/docs/"
into "docs"
}
//上传到JCenter所需要的源码文件
artifacts {
archives javadocJar
archives sourcesJar
}
//解决 JavaDoc 中文注释生成失败的问题
tasks.withType(Javadoc) {
options.addStringOption('Xdoclint:none', '-quiet')
options.addStringOption('encoding', 'UTF-8')
options.addStringOption('charSet', 'UTF-8')
}
//发布到 Bintray
publish {
userOrg = 'duanruirui' //bintray.com 注册的用户名
groupId = 'com.jcenterlibrary' //以后访问 jcenter上此项目的路径,一般和库项目的包名一致
artifactId = 'JCenterDemo' //bintray.com 创建的 Package 名
publishVersion = '1.0.13' //版本号
desc = '这是一个不认真的版本说明' //版本说明,随意
website = 'https://github.com/DRPrincess/DR_MavenDemo' //关于这个开源项目的网站,随意
}
关于 publish 的参数,以上只是一部分,其实还有很多,具体看 配置publish闭包说明 ,需要解释一下,bintray-release 默认发布到 maven 仓库,这也是上一步 Add New Repository
时,Name 建议填写 maven
的原因。如果有需要,需要自定义 Publication,详看 自定义 Publication。
上一步,我们 Add New Package
创建的 Package 的名字这里也用到了,原因在于,当三方库上传到 Maven 仓库后,Gradle 的引用路径是:
compile groupId:artifactId:version
groupId : 以后访问 jcenter上此项目的路径,一般和库项目的包名一致。
artifactId : 就是 Add New Package
创建的 Package 的名字 。
version : 三方库的版本号。
以上两部配置准备完毕,在 rootProject 的路径下执行这句命令即可完成上传。
./gradlew clean build generatePomFileForReleasePublication bintrayUpload -PbintrayUser=BINTRAY_USERNAME -PbintrayKey=BINTRAY_KEY -PdryRun=false
这行命令的中两个参数 BINTRAY_USERNAME
和BINTRAY_KEY
,需要换上你自己的bintray.com 账号信息,分别是用户名和 API Key。用户名很好得到,API Key 通过下图方式,可以拿到:
如果命令执行成功,会看到 BUILD SUCCESSFUL
字样。
然后去 Bintray 网站 登录后,就可以看到上传的的项目了,右侧可以看到上传的版本,我测试过很多回,截止到我截图的时间已经到 1.0.6了。
点击 Files,可查看上传的文件,如下是 1.0.6 版本上传的文件:
文件 | 意义 |
---|---|
JCenterDemo-1.0.6-javadoc.jar | 生成的 java 注释说明文档 |
JCenterDemo-1.0.6-sources.jar | 项目源码,有这个之后,引用该库的时候,可以点进入看到源码 |
JCenterDemo-1.0.6.aar | Android 库项目的归档文件,这是必不可少的文件 |
JCenterDemo-1.0.6.pom | Maven的基础。它是一个XML文件,包含了 Maven 用来构建项目所需要的项目配置的信息,aar 是不能将库的依赖打进去的,那些依赖会记在 pom 文件中。 |
上传过程中,我祝福你不会遇到错误的情况,但是出现了,也不要烦躁,坑这个东西踩着踩着就平了,遇到错误去 bintray-release 的 issues 中查一下,或者问问谷爹,基本都能找到解决方法。
以下我遇到的问题:
01:只上传了aar
文件,没有生成 pom 文件
bintray-release 的文档上给出的命令 ./gradlew clean build bintrayUpload
只上传了 aar
文件,于是添加了一个 generatePomFileForReleasePublication
,解决了这个问题,最终版就是上面示例的命令。
02:其他三个文件都上传了,但是没有上传aar
文件
这个问题,一般是项目构建失败导致的,我是因为资源文件名字重复,很奇怪,构建失败,但是其他文件上传上去了。遇到这个文件,仔细看一下构建的输出原因,总能解决的。
03:Could not upload to ‘xxx’: HTTP/1.1 409 Conflict [message:Unable to upload files: An artifact with the path ‘xxx’ already exists]
Maven 不能重复同一个版本,如果上传新版本,版本号要修改以下,一般是 +1 递增。
04:Javadoc 文档生成失败,导致 build Failed
错误信息:
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':jcenterlibrary:javadoc'.
> Javadoc generation failed. Generated Javadoc options file (useful for troubleshooting): '/Users/admin/AndroidStudioProjects/DR_MavenDemo/jcenterlibrary/build/tmp/javadoc/javadoc.options'
是因为中文注释的原因导致,修改 JavaDoc 的编码,就可以正常生成和显示了。解决方法是 Library Module 的 build.gradle 中添加下列代码:
//解决 JavaDoc 中文注释生成失败的问题
tasks.withType(Javadoc) {
options.addStringOption('Xdoclint:none', '-quiet')
options.addStringOption('encoding', 'UTF-8')
options.addStringOption('charSet', 'UTF-8')
}
最后一步,上传到 JCenter 中央仓库
未曾接触过这个的我,对这最后一步表示有很大的疑惑:
因为在上一步,我们已经将库项目已经推送到远程了,那为什么要有最后这一步呢?
在第三步项目成功上传后,已经开始使用 Gradle 依赖该开源库,在 Package 页面点击 Gradle 可以看到对应的依赖命令。
然后我试了下,发现要使用的话,会报找不到库的错误(1.0.8 的时候忘记截图了,用 1.0.14 测试的,道理是一样的,报错原因是因为找不到这个三方库),如下图:
如果想正确引用,需要将远程库所在 Repository 地址告诉 Gradle,这个地址从 Bintray 网站可以拿到,如下图:
然后 rootProject 的 build.gradle 中添加如下内容,即可正确引用:
allprojects {
repositories {
google()
jcenter()
maven { url 'https://dl.bintray.com/duanruirui/maven' } //添加
}
}
那为什么使用其他第三方库,不需要加上三方库作者的 maven 地址呢?
就是因为作者将三方库同步到 JCenter 的中央仓库了。jcenter()
就是中央仓库的地址。所以为了方便使用,去掉这个三方库所在 maven 仓库地址的额外引用,我们最好将库同步到 JCenter 中央仓库。
同步的步骤非常简单,Package 详情页面有一个 Add to JCenter
按钮,点击进入,填写同步的理由,提交申请即可。通过之后会给发消息通知的。
审核的速度还是非常快的,上午提交的,下午就收到了通过的站内信,如下图所示:
现在已经同步到 JCenter 中央仓库,只通过一句代码引用你的第三方库啦~
以上是本博客的全部内容,博客测试用的 Demo 我放在了 GitHub 上,地址在此:DR_MavenDemo,有问题欢迎提 issue。
之前没接触过这方面的知识,尝试使用的时候,再次感觉到自己的学识浅薄,实现过程中出现一些问题,大多一知半解,不知道问题的本质,希望以后的学习中,能够深入些,了解更多一点。
于是,下篇博客《Android-Nexus 搭建自己的 Maven 仓库 & Gradle 上传依赖包》,继续出发!
《Maven与nexus》
《How to publish Android Library on Bintray/JCenter》
《放弃JitPack,发布Android Library到Bintray、JCenter》
《 Android 快速发布开源项目到jcenter》