本文将详细讲解2个maven仓库jcenter、mavenCenter的创建、注册、发布、上传及其怎样将jcenter中发布的文件自动上传到mavenCenter。
何为jcenter,mavenCenter?
jcenter。
jcenter是一个由 bintray.com维护的Maven仓库 。你可以在这里看到整个仓库的内容。
我们在项目的build.gradle 文件中如下定义仓库,就能使用jcenter了:
allprojects {
repositories {
jcenter()
}
Maven Central
Maven Central 则是由sonatype.org维护的Maven仓库。你可以在这里看到整个仓库。
注:不管是jcenter还是Maven Central ,两者都是Maven仓库
我们在项目的build.gradle 文件中如下定义仓库,就能使用Maven Central了:
allprojects {
repositories {
mavenCentral()
}
}
为什么会有2个maven标准库?为什么android studio早期自动引入的是mavenCenter库,之后却换成了jcenter这个标准库?
虽然jcenter和Maven Central 都是标准的 android library仓库,但是它们维护在完全不同的服务器上,由不同的人提供内容,两者之间毫无关系。在jcenter上有的可能 Maven Central 上没有,反之亦然。
事实上两个仓库都具有相同的使命:提供Java或者Android library服务。上传到哪个(或者都上传)取决于开发者。
起初,Android Studio 选择Maven Central作为默认仓库。如果你使用老版本的Android Studio创建一个新项目,mavenCentral()会自动的定义在build.gradle中。
但是Maven Central的最大问题是对开发者不够友好。上传library异常困难。上传上去的开发者都是某种程度的极客。同时还因为诸如安全方面的其他原因,Android Studio团队决定把默认的仓库替换成jcenter。正如你看到的,一旦使用最新版本的Android Studio创建一个项目,jcenter()自动被定义,而不是mavenCentral()。
有许多将Maven Central替换成jcenter的理由,下面是几个主要的原因。
jcenter通过CDN发送library,开发者可以享受到更快的下载体验。
jcenter是全世界最大的Java仓库,因此在Maven Central 上有的,在jcenter上也极有可能有。换句话说jcenter是Maven Central的超集。
上传library到仓库很简单,不需要像在 Maven Central上做很多复杂的事情。
友好的用户界面
如果你想把library上传到 Maven Central ,你可以在bintray网站上直接点击一个按钮就能实现。
仓库中存储的有两种类型的library:jar 和 aar。jar文件大家都知道,但是什么是aar文件呢?
aar文件
aar文件时在jar文件之上开发的。之所以有它是因为有些Android Library需要植入一些安卓特有的文件,比如AndroidManifest.xml,资源文件,Assets或者JNI。这些都不是jar文件的标准。
因此aar文件就时发明出来包含所有这些东西的。总的来说它和jar一样只是普通的zip文件,不过具有不同的文件结构。jar文件以classes.jar的名字被嵌入到aar文件中。其余的文件罗列如下:
- /AndroidManifest.xml (mandatory)
- /classes.jar (mandatory)
- /res/ (mandatory)
- /R.txt (mandatory)
- /assets/ (optional)
- /libs/*.jar (optional)
- /jni//*.so (optional)
- /proguard.txt (optional)
- /lint.jar (optional)
在了解以上关于maven库的基本概念之后,要进行maven库的各种操作还必须了解build.gradle这个脚本文件,而了解这个文件就不行了解groovy动态脚本语言及其task,project,plugin等各种概念。这些东西足够写上好几篇文章了,本文主要对maven库的各种操作进行讲解,因此以上概念请查看相关技术文章,有助于来理解本文后续内容。
怎样上传jar、aar等到jcenter?
1、首选需要创建注册一个bintray账户,注册网址:https://bintray.com。
注册bintray账户的时候请注意一个问题,bintray账户分为企业账户和个人账户,对于个人来说最好注册个人账户,因为个人账户在把上传的内容推送到远端的时候需要执行 Add to JCenter按钮,只有点击这个按钮才能把上传的包推向远程;而企业账户最开始注册是没有这个按钮的,因为企业账户需要审核,可能会长到一个月。
2、账户注册完毕之后,回到android studio的build.gradle,开始脚本编程了。
标准脚本格式,可以完全贴入build.gradle中,替换相关内容即可。
标准jcenter发布脚本:
//必须引入这2个插件
apply plugin : 'com.github.dcendents.android-maven'
apply plugin : 'com.jfrog.bintray'
// This is the library version used when deploying the artifact
group = PROJ_GROUP
version = PROJ_VERSION //PROJ_VERSION 替换成自己的的版本号
install {
repositories.mavenInstaller {
// This generates POM.xml with proper parameters
pom {
project {
packaging 'aar'
description PROJ_DESCRIPTION //替换成自己的工程描述
// Add your description here
name PROJ_POM_NAME //替换成自己的工程名称
url PROJ_WEBSITEURL //替换成自己的工程网络地址,例如github中发布的源码地址
// Set your license
licenses {
license {
name PROJ_LICENCE_NAME //替换证书类型,例如'The Apache Software License, Version 2.0'
url PROJ_LICENCE_URL //替换证书地址,例如'http://www.apache.org/licenses/LICENSE-2.0.txt'
distribution PROJ_LICENCE_DEST //证书描述
}
}
developers {
developer {
id DEVELOPER_ID //替换成自己的id
name DEVELOPER_NAME //替换成自己的名字
email DEVELOPER_EMAIL //替换成自己的邮箱
}
}
scm {
connection PROJ_VCSURL //替换成自己的Git仓库地址。
developerConnection PROJ_VCSURL //替换成自己的Git仓库地址。
url PROJ_WEBSITEURL //替换成自己的项目主页。
}
}
}
}
}
task sourcesJar(type : Jar) { //这个task不需要修改,发布内容为jar类型
classifier = 'sources'
}
task javadoc(type : Javadoc) { //这里不需要修改,发布的有javaDoc
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
failOnError = false
}
task javadocJar(type : Jar, dependsOn : javadoc) { //这里也不需要修改
classifier = 'javadoc'
from javadoc.destinationDir
}
artifacts { //这里不需要修改,发布内容包括javadocJar和sourcesJar
archives javadocJar
archives sourcesJar
}
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
bintray {
user = properties.getProperty("bintray.user")
key = properties.getProperty("bintray.apikey")
configurations = ['archives']
pkg {
repo = "maven"
name = PROJ_NAME //替换成自己的
websiteUrl = PROJ_WEBSITEURL //替换成自己的
vcsUrl = PROJ_VCSURL //替换成自己的
licenses = ["Apache-2.0"]
//userOrg = "angryboby" //组织名称,换成自己的
publish = true //这个必须设置为true,默认为false只有这样才能发布
version {
desc = PROJ_DESCRIPTION //替换成自己的
//gpg的配置是在为jcenter自动上传到mavenCenter做准备,没有本签名配置无法将包同步到mavenCenter,因为只有经过签名的包才允许上传到maveCenter.
gpg {
sign = true //Determines whether to GPG sign the files. The default is false
passphrase = properties.getProperty("bintray.gpg.password")
//注意,这里是在生成mavenCenter公钥和密钥时候的密码,后面后解释
}
}
}
}
以上是build.gradle中jcenter上传、发布的标准脚本,里面的内容替换成自己的即可,以下将贴出这篇文章demo的代码以供参考。
本demo需要publish到jcenter的是一个android library工程mavenlibrary。
apply plugin: 'com.android.library'
//这里添加下面两行代码。
apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'com.jfrog.bintray'
android {
compileSdkVersion 24
buildToolsVersion "25.0.0"
defaultConfig {
minSdkVersion 15
targetSdkVersion 24
versionCode 3
versionName "3.0.6"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:24.0.0'
testCompile 'junit:junit:4.12'
}
group = "com.github.qiubowang"
version = "3.0.6"
def siteUrl = 'https://github.com/qiubowang/study'
def gitUrl = 'https://github.com/qiubowang/study.git'
install {
repositories.mavenInstaller {
// 生成pom.xml和参数
pom {
project {
packaging 'aar'
// 项目描述,复制我的话,这里需要修改。
name 'mavenlibrary'// 可选,项目名称。
description 'The Android build the framework of the Http server.'// 可选,项目描述。
url siteUrl // 项目主页,这里是引用上面定义好。
// 软件开源协议,现在一般都是Apache License2.0吧,复制我的,这里不需要修改。
licenses {
license {
name 'The Apache Software License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
//填写开发者基本信息,复制我的,这里需要修改。
developers {
developer {
id 'qiubo' // 开发者的id。
name 'qiubo' // 开发者名字。
email 'wangqiubo2018@126.com' // 开发者邮箱。
}
}
// SCM,复制我的,这里不需要修改。
scm {
connection gitUrl // Git仓库地址。
developerConnection gitUrl // Git仓库地址。
url siteUrl // 项目主页。
}
dependencies{
dependency{
groupId "com.github.qiubowang"
version "3.0.6"
artifactId "mavenlibrary"
scope "compile"
}
}
}
}
}
}
// 生成jar包的task,不需要修改。
task sourcesJar(type: Jar) {
from android.sourceSets.main.java.srcDirs
classifier = 'sources'
}
// 生成jarDoc的task,不需要修改。
task javadoc(type: Javadoc) {
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
// destinationDir = file("../javadoc/")
failOnError false // 忽略注释语法错误,如果用jdk1.8你的注释写的不规范就编译不过。
}
// 生成javaDoc的jar,不需要修改。
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
artifacts {
archives javadocJar
archives sourcesJar
}
Properties properties = new Properties();
properties.load(project.rootProject.file('local.properties').newDataInputStream())
def bintray_user = properties.getProperty("bintray.user")
def bintray_key = properties.getProperty("bintray.apikey")
def bintray_gpg_pwd = properties.getProperty("bintray.gpg.password")
bintray {
user = bintray_user
key = bintray_key
configurations = ['archives']
pkg {
repo = "androidLibary"
name = "mavenlibrary"
// userOrg = "angryboby"
websiteUrl = siteUrl
vcsUrl = gitUrl
licenses = ["Apache-2.0"]
publish = true
version{
gpg{
sign = true
passphrase = bintray_gpg_pwd
}
}
}
}
以上脚本中bintray_user,bintray_key,bintray_gpg_pwd的配置在local.properties中,如下截图:
以上有些问题需要解决,user指的是什么呢?还记得bintray注册的账户吗?即是你注册的用户名,见下图:
bintray.apikey又指的什么?请见下图,一目了然:
bintray.gpg.password指的什么呢?这2个是生成maveCenter公钥和私钥过程中的相关设置,后续会进行讲解。
3、登录进bintray账户,开始配置远程仓库了,按照截图和文字提示配置即可。
创建仓库成功之后,则接着add package,add package按照以下截图及其文字说明配置。
4、创建 bintray仓库 和 package成功之后,则就可以在android studio中执行脚本publish到jcenter仓库了。
在Android studio 中的 Terminal 中依次执行以下命令(命令行中执行也是可以的):
gradlew clean 清理工程
gradlew install 编译,必须执行成功
gradlew bintrayUpload 上传,如果提示success ,则说明已经上传成功,一般会卡在97%出一会,跟网络和上传的文件大小有关。
见下图:
当gradlew bintrayUpload 提示 BUILD SUCCESSFUL之后,证明已经上传成功,则刷新bintray网址,可以发现文件已经生成,并且版本号和 build.gradle设置的一致,例如本次demo中的截图:
点进3.0.6之后界面如下:
选择Files,这可以看见已经发布的文件:
5、以上上传上去的文件其实还在本地库,并没有上传到远程库,那么怎样才能将上传的文件推向远程库呢?进入本demo中的mavenlibrary包,Linked to (0) 标签右边有一个 Add to JCenter按钮,点击推送即可:
见下图:
点击推送之后,则需要等待bintray团队审核我们的请求,大概2-3个小时。一旦同步的请求审核通过,你会收到一封确认此更改的邮件。现在我们去网页上确认,你会在 Linked To 部分看到一些变化。
一旦审核通过,请见下图截图,Linked To标签部分会变成如下:
6、文件已经成功发布到远程,其他人根据地址就可以引用那些库文件了!按照下图操作即可知道发布的远程库地址:
经过多次努力,工程文件终于上传到jcenter的中央库了,每个人根据地址就可以在build.gradle使用发布的库文件。按说到此anddoid工程和jcenter的关联已经完毕,那么可以不可以将刚才生成的文件也同步到mavenCenter呢,当然是可以的,以下将讲解如何将jcenter自动化上传到mavenCenter,这样2个maven标准仓库同时将拥有我们发布的文件。
7、按照mavenCenter发布的流程,首先必须本地生成公钥和私钥。经过公钥和私钥签名的包,才能成功上传到mavenCenter中央库。公钥和私钥通过GPG工具来生成。以下将讲解在window系统下的公钥和私钥的生成。
window下首选安装 gpg4win-2.3.4.exe 和 Cygwin,gpg命令本身是跑在UNIX平台下的,因此需要安装一个模拟环境,Cygwin即是在windows平台上运行的类UNIX模拟环境。(Cygwin命令行中执行以下命令)
gpg加密详情可以参考:http://www.ruanyifeng.com/blog/2013/07/gpg.html
执行$ gpg –version,运行结果见下图:
执行$ gpg –gen-key,则生成证书,生成证书中可能会让你选择2048字节,按照提示输入即可,生成key的过程会显示以下信息(需要注意的是这个过程需要设置密码,这个密码必须记住,bintray.gpg.password这里会使用到):
执行$ gpg –list-keys,查看keys,如果显示以下信息证明成功:
现在把key上传到keyserver让它发挥作用。为此,请调用如下的命令并且将其中的PUBLIC_KEY_ID替换成上面pub 2048R/ 1CB1F9C0 的8位16进制值,譬如本例是1CB1F9C0。
gpg –keyserver hkp://pool.sks-keyservers.net –send-keys PUBLIC_KEY_ID
执行以上命令,pub的key就上传到服务器,就可以使用了。
执行$gpg -a –export yourmail@email.com > public_key_sender.asc
$gpg -a –export-secret-key yourmail@email.com > private_key_sender.asc
换上自己的邮件地址既可,导出的私钥和公钥地址如下(我的是在D盘,和Cycwin的安装路径有关):
**8、**gpg的keys已经生成完毕,则目前就需要在bintray中配置GPG了,GPG将是jcenter自动同步到mavenCenter必经一步,将上图公钥和密钥负责到一下截图中既可。
9、还记得最开始提到的build.gradle脚本gpg的设置吗?这个设置是对发布的包进行签名,只有经过公钥、密钥签名的才会上传到mavenCenter。
version{
gpg{
sign = true
passphrase = bintray_gpg_pwd //这个密码即是local.property中的bintray.gpg.password,进而是在执行 $ gpg --gen-key**过程中有一项是需要设置密码的那个密码
}
}
10、*bintray和build.gradle已经配置完毕,则要上传到mavenCenter首选需要在 https://issues.sonatype.org* 上注册一个账号。
注册成功登陆进去,按照以下截图的步骤来向sonatype申请一个仓库。
请按照以上截图申请,这里的issue可能最开始不习惯,其实就是无论你申请一个mavenCenter仓库,还是提交一个更新,都是以issue的形式存在。还有一般申mavenCenter仓库,需要2-3个工作日才会成功,如果没有通过,根据工作人员的修改重新提交即可,最好在Comment中和美国那边的工作人员交流下,例如以下截图,本人英文不是很好,请见谅……..
11、等待mavenCenter仓库审核通过之后,现在就可以将jcenter中上传的文件同步到mavenCenter仓库了,同步过程见下图:
如果有以下提示,证明jcenter远程仓库的文件已经同步到mavenCenter了,如图所示:
12、那现在就看看,到底jcenter仓库的文件有没有同步到mavenCenter中,通过以下截图可以发现demo中的文件确实已经成功的上传。(查看mavenCenter发布的远程地址为:https://oss.sonatype.org/content/repositories/releases/com/github/qiubowang/mavenlibrary/,后面的是个人工程的gourp id)。
以上是非常完整和详尽的2个标准maven仓库的全流程,还有很多小细节就各自摸索了,这里就不再讲解,有问题可以留言,mavenCenter本身自己的publishing就等后续再开一个小篇幅讲解,篇幅限制这里就不啰嗦。原创作品,请尊重版权,转接请附上原创地址!