如何通过Android Studio发布library到jCenter和Maven Central


在Android Studio里,如果你想引入任何library到自己的项目中,只需要很简单的在module的build.gradle文件中添加一行依赖。

dependencies {
    compile 'com.inthecheesefactory.thecheeselibrary:fb-like:0.9.3'
}

就是这么简单,library已经可以在自己的项目中使用。

这看起来非常酷,但你也许会好奇Android Studio是从哪里去抓取到这些library的?这篇博客会详细讲解如何发布自己的library,使之能够与全世界的开发者分享,这不仅使得世界更加美好,也让自己看起来更酷。

Android Studio是从哪里去抓取到这些library的?

用这个简单的问题开始,我相信不是所有的人都确切的知道Android Studio是从哪里抓取到这些library的。它是通过Google去搜索,然后下载到我们项目中的么?

好吧,其实并不复杂。Android Studio是从我们定义在build.gradle文件中的Maven资源中心去下载library的。(Apache Maven是Apache为开发者提供的一个发布libraries的文件服务工具)。基本上,现在有两种标准的libraries仓库,分别是jCenterMaven Central

jcenter

jcenter是一个托管在bintray.com的资源库。你可以在这里找到需要的资源。
为了能在你的项目中使用jcenter,你需要像下面一样,在自己的build.gradle文件中定义自己的资源库。

allprojects {
    repositories {
        jcenter()
    }
}

Maven Central

Maven Central是一个托管在sonatype.org的资源库。你可以在这里找到需要的资源。
为了能在你的项目中使用Maven Central,你需要像下面一样,在自己的build.gradle文件中定义自己的资源库。

allprojects {
    repositories {
        mavenCentral()
    }
}

请注意,虽然jcenter和Maven Central都是标准android library资源仓库,但他们的托管地址完全不同,它们的内容是由不同提供者提供的,而且之间并没有任何关联。所以也就可能,在jcenter中能够找到的library,在Maven Central和viceversa中并不能找到。

除了这两个标准的资源库外,我们也可以定义特殊的资源库,引入一些开发者托管在自己服务器上的library。Twitter的Fabric.io就完全是托管在自己服务器上的Maven资源库。如果你想要使用任何fabric.io上面的library,都需要向下面一样,定义资源库的url。

repositories {
    maven { url 'https://maven.fabric.io/public' }
}

然后你可以通过和下面相似的方法获取该资源库里面的任何library。

dependencies {
    compile 'com.crashlytics.sdk.android:crashlytics:2.2.4@aar'
}

但是哪一种方式更好呢,是上传library到标准的服务器上,还是搭建自己的服务器?为了让我们的library能够被大众所使用,建议上传到标准服务器上。其他开发者只需一行代码定义依赖名字而无需其他操作。在这篇博客中,我们只关注jcenter和Maven Central这两种能够给开发者提供更好方式的资源库。

事实上,android stuido还存在除Maven外的另一种类型的资源库,叫做Ivy Repository,但从我个人的经验来看,我还从未见过任何人使用它,所以这篇博客先简单的忽略这种类型。

Understand jcenter and Maven Central

想知道为什么是两个标准资源库而不是一个?
事实上,它们都拥有相同的职责:托管java/Android library。完全由开发者决定把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里面也能找到。
- 非常容易上传library到jcenter仓库,没有必要签名或做其他一些在Maven Central上很复杂的操作。
- 界面友好
- 如果你想上传library到Maven仓库,在bintray网站单击即可(一次性设置)。

通过以上的原因以及我自己的经验,我必须说,把jcenter作为默认仓库是非常明智的决定。
所以,这边博客主要关注jcenter,一旦你把library成功上传到jcenter,那么也可以非常方便的再上传到Maven Central。

gradle是如何把library从仓库拉取下来的?

当我们讨论如何把library上传到jcenter之前,我们先讨论下gradle是如何从仓库抓取library的。例如,当我们像下面这样在build.gradle里面定义依赖的时候,library文件是如何下载到你的项目的。

compile 'com.inthecheesefactory.thecheeselibrary:fb-like:0.9.3'

首先我们得了解library字符串的格式,它包含三个部分:

GROUP_ID:ARTIFACT_ID:VERSION

以上面的字符串为例:
GROUP_IDcom.inthecheesefactory.thecheeselibraryARTIFACT_IDfb-likeVERSION0.9.3
GROUP_ID定义了library的组,很可能不同功能的library存在于同一背景下,如果library在相同的组,那么它们共享相同的GROUP_ID。通常我们用开发者的包名加上library的名字作为GROUP_ID,例如com.squareup.picasso,然后我们再定义真正的library名作为ARTIFACT_ID。关于VERSION,就是版本号,虽然它可以是任意字符,但我建议它设置为x.y.z的格式,如果你愿意,也可以跟上-beta。
这有一些真实的library例子,你会注意到,每一个都很容易辨别出library的名字和包名。

dependencies {
  compile 'com.squareup:otto:1.3.7'
  compile 'com.squareup.picasso:picasso:2.5.2'
  compile 'com.squareup.okhttp:okhttp:2.4.0'
  compile 'com.squareup.retrofit:retrofit:1.9.0'
}

像上面一样添加了依赖会发生什么呢?很简单,Gradle会向Maven仓库服务器询问library是否存在,如果存在,则会返回library的下载地址,通常是GROUP_ID/ARTIFACT_ID/VERSION_ID的格式,例如,你可以从http://jcenter.bintray.com/com/squareup/otto/1.3.7https://oss.sonatype.org/content/repositories/releases/com/squareup/otto/1.3.7/找到com.squareup:otto:1.3.7的library文件。
然后Android Studio会下载这些文件到我们的机器上,再编译到我们的项目中,就是这样,没什么复杂的!

我相信,你已经很清楚的知道,从远程仓库拉下来的,不过是托管在服务器上的jar或arr格式的文件。相对于自己去下载这些文件,单独拷贝编译到自己的项目,这种方式最大的好处是只需要定义一些依赖文本,而不需要其他更多的操作。

了解aar文件格式

等等,我说过这儿有两种形式的library托管在远程仓库里,jar和aar,jar倒是常用的,我相信大家都知道,不过,aar文件又是什么呢?

aar文件是更进一步的jar文件,它被创造出来是因为一些Android Library需要嵌入一些android的特殊文件,比如AndroidManifest.xml, Resources, Assets or JNI等jar文件不包含的内容。所以aar文件被创造出来解决这些问题。一般说来,jar只是有着不同结构的zip文件,jar文件被嵌入在aar文件里,名为class.jar。aar中余下部分如下:

  • /AndroidManifest.xml (mandatory)
  • /classes.jar (mandatory)
  • /res/ (mandatory)
  • /R.txt (mandatory)
  • /assets/ (optional)
  • /libs/*.jar (optional)
  • /jni/<abi>/*.so (optional)
  • /proguard.txt (optional)
  • /lint.jar (optional)

正如你所看见的,aar文件是专门为Android设计的,所以这篇博客将会告诉你如何创建并上传一个aar格式的library。

如何上传你的library到jcenter

到现在,我相信你对远程library仓库的工作模式已经有了基本的了解。现在开始最重要的环节:上传过程。目标很简单,即如何将我们的库文件上传到http://jcenter.bintray.com。一旦我们学会了上传,那么library也就能够被发布了。两个问题需要关注:如果创建aar文件以及如何上传编译好的文件到远程仓库。
虽然它需要很多步骤,但我必须说,这完全不困难,因为bintray已经为我们准备好了一切。你可以通过下面的图了解整个过程。


因为有很多细节,所以我把整个过程分为了7部分,以便能够循序渐进的描述清楚。

Part 1 : 在Bintray上创建一个包

首先,你需要在bintray上创建一个包,为了完成这步,你需要一个bintray账号并且在网站上创建一个包。
第一步:在bintray.com上注册账号。
第二步:注册成功后,登陆网站点击maven


第三步:点击Add New Package,为你的library创建一个新的包。

第四步:输入必要的信息

虽然如何命名包名没有明确的规则,但有一些约定:所有字符小写,单词间通过“-”号连接,比如,fb-like。
一旦上面每一步都完成了,单击Create Package完成创建。

第五步:网站会自动重定向到编辑页面。点击包名下面的名字可以进入具体的信息页面。


好了,现在你已经在bintray上有了自己的Maven仓库,准备好上传自己的library文件了。

Bintray账号的注册工作已经完成了,接下来将会和Maven Central的提供者,Sonatype打交道。

Part 2 : 为Maven Central创建一个Sonatype账号

提示:如果你没有计划上传library文件到Maven Central,你可以跳过第二部分和第三部分。但无论如何,我建议不要跳过,因为还是有很多的开发者在用这个仓库。
就想jcenter一样,如果你想要上传你的library到Maven Central,你需要在它的提供者,也就是Sonatype网站上注册一个账号。
你所需要知道的是,你必须在Sonatype网站上创建一个JIRA Issue Tracker的账号。为了完成这一步,请到Sonatype Dashboard注册。
一旦你完成注册,你需要请求发布library到Maven Central。虽然这个过程可能没有任何意义(至少对我来说),但你必须在JIRA上创建一个请求,让他们允许你上次你的library到Maven Central。
为了创建一个问题描述,到Sonatype Dashboard网站,通过账号登陆,然后点击顶部的Create按钮。


填入以下的信息:
Project: Community Support - Open Source Project Repository Hosting
Issue Type: New Project
Summary: 你library文件的名称,例如:Cheese Library
Group Id: 填入GROUP_ID的根名称,例如:com.inthecheeselibrary。在你得到批准之后,每个以com.inthecheeselibrary开头的library文件,都会被允许上传的远程仓库,例如:com.inthecheeselibrary.somelib
Project URL: 填入一个你准备用来描述该library的地址,例如:https://github.com/nuuneoi/FBLikeAndroid
SCM URL: 源码管理的地址,例如:https://github.com/nuuneoi/FBLikeAndroid.git

保持没有修改的部分,点击Create。我们要做的结束了,接下来是最难的部分:耐心等待。大概需要一周的时间审核,然后才能在Maven Central中访问自己的library。

最后要做的是,在Bintray Profile的账号选项卡页面,填入Sonatype OSS的用户名。


点击Update,这个部分我们就完成了。

Part 3 : 在Bintray上开启自动签名

正如上面提到的,我们可以通过jcenter上传一个library到Maven Central,但前提是,我们需要对library进行签名。bintray提供一个自动化的工具,允许通过网络接口上传的library能够在上传后自动签名。
第一步是通过命令行,生成一个key。(如果使用的是windows,请在cygwin环境下操作)

gpg --gen-key

这里有一些强制性填充的字段,大部分情况下用默认值就可以,但是对于一些字段,需要填入你自己的信息,比如,你的真实姓名,密码等等。
一旦key被创建,调用下面的命令行,可以看到key的信息。

gpg --list-keys

如果没有出错,信息会像下面一样被展示出来。

pub   2048R/01ABCDEF 2015-03-07
uid                  Sittiphol Phanvilai <yourmail@email.com>
sub   2048R/98765432 2015-03-07

现在我们需要上传公钥到管理中心使它生效。为了完成这一步,请调用下面的命令行,其中替换PUBLIC_KEY_ID为2048R/后面的8位16进制数,在这个例子中,即为:01ABCDEF。

gpg --keyserver hkp://pool.sks-keyservers.net --send-keys PUBLIC_KEY_ID

接下来,通过以下命令,以ASCII格式导入公钥和私钥,请替换其中的yourmail@email.com为前面你生成key所使用的email。

gpg -a --export yourmail@email.com > public_key_sender.asc
gpg -a --export-secret-key yourmail@email.com > private_key_sender.asc

打开Bintray的Edit Profile页面,点击GPS Signing。填入在前面步骤中导出的public_key_sender.asc和private_key_sender.asc文件里面的公钥和私钥。


点击Update保存key。
最后一步是开启自动签名,到Bintray的主页,点击maven,再点击Edit。

选中GPG Sign uploaed files automatically的勾选框,开启自动签名。

点击Update保存,到现在为止,每一个单独的library上传到Maven仓库都能够被自动签名,而且已经准备好一键发布到Maven Central。
请注意,这是一个一次性行为,将会被应用到以后每一个创建的library中。
Bintray和Maven Central的部分都已经准备好了,现在让我们切换到Android Studio部分。

Part 4 : 准备Android Studio工程项目

在许多情况下,我们可能在一个项目里,需要上传多个library,也可能不需要。所以我建议最好的结构是按照Module来划分,基本上我建议最少有两个Module,一个应用程序的Module,一个包含了你想要上传到远程仓库源码的library的Module。请注意,如果在你的项目里不止包含了一个library,请创建另外一个Module:每一个library对应一个Module


我相信大家都知道如何创建一个library module,多以我不会太深入的讲这个部分。

接下我们需要把bintray的插件应用到你的项目中。要做到这一点,我们需要像下面这样修改project的build.gradle文件中的依赖部分。

dependencies {
    classpath 'com.android.tools.build:gradle:1.2.3'
    classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
    classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'
}

gradle构建工具的版本需要在1.1.2以上,因为之前的版本存在一个严重的bug。在这个例子中,我们选择使用1.2.3版本。
接下来,我们需要修改local.properties,定义用于bintray身份认证的用户名和api密钥,以及密码。

之所以把这些信息放到这个文件中,是因为一些敏感信息,包括版本控制,不应该被共享。幸运的是,自从项目被创建,local.properties文件就已经被添加了.gitignore,所以这些敏感信息不会意外上传到git服务器。

下面是需要添加的配置信息:

bintray.user=YOUR_BINTRAY_USERNAME
bintray.apikey=YOUR_BINTRAY_API_KEY
bintray.gpg.password=YOUR_GPG_PASSWORD

把你在bintray上的用户名写到第一行,把你在Edit Profile网页上,API Key的信息写到第二行。最后一行是你在前面步骤中,用来创建GPG key的密码。最后保存并关掉这个文件。

最后需要修改的文件是module的build.gradle文件。打开它并把下面的信息添加到里面。

apply plugin: 'com.android.library'
 
ext {
    bintrayRepo = 'maven'
    bintrayName = 'fb-like'
 
    publishedGroupId = 'com.inthecheesefactory.thecheeselibrary'
    libraryName = 'FBLike'
    artifact = 'fb-like'
 
    libraryDescription = 'A wrapper for Facebook Native Like Button (LikeView) on Android'
 
    siteUrl = 'https://github.com/nuuneoi/FBLikeAndroid'
    gitUrl = 'https://github.com/nuuneoi/FBLikeAndroid.git'
 
    libraryVersion = '0.9.3'
 
    developerId = 'nuuneoi'
    developerName = 'Sittiphol Phanvilai'
    developerEmail = 'sittiphol@gmail.com'
 
    licenseName = 'The Apache Software License, Version 2.0'
    licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
    allLicenses = ["Apache-2.0"]
}

保持bintrayRepo为现在这个样子,改变bintrayName为你自己的包名,修改其他配置来匹配你自己的library信息。有了上面的脚本,每个人都可以通过下面一行gradle脚本使用这个library。

compile 'com.inthecheesefactory.thecheeselibrary:fb-like:0.9.3'

最后一步是应用两个脚本,用于创建library文件以及上传构建文件到bintray,在build.gradle文件的最后添加以下脚本即可(为了方便,我直接把这些文件链接到github的服务器上)。

// Place it at the end of the file
apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'

现在,你的项目已经设置并且准备好了上传到bintray。

Part 5 : 上传你的library到bintray空间

现在是时候上传你library到你自己的bintray仓库了。首先,请切换到Android Studio的Terminal界面。



第一步是检查代码的正确性,构建library文件(aar,pom,等等)。输入下面的命令。

> gradlew install

如果没有任何错误,将会显示下面的命令行:

BUILD SUCCESSFUL

我们已经完成了一半,接下来需要上传构建文件到bintray,输入下面的命令行:

> gradlew bintrayUpload

如果显示下面这行,那就成功了:

SUCCESSFUL

在bintray网站的界面上检查你的包,你会发现版本区域有了变化。



点击它切换到Files页面,你会看到上传的library文件。



恭喜,现在你的library已经在线上,可以被任何人使用。
但是,到你的library还只在Maven仓库里,而没有在jcenter,所以任何想要使用你的library的人,都必须像下面这样定义:
repositories {
    maven {
        url 'https://dl.bintray.com/nuuneoi/maven/'
    }
}
 
...
 
dependencies {
    compile 'com.inthecheesefactory.thecheeselibrary:fb-like:0.9.3'
}

你可以从bintray网站界面上,找到你自己Maven仓库的url,也可以简单的用你的bintray用户名替换nuuneoi。我建议你进入网页,看看具体是怎么回事。

正如上面所提到的,让开发者定义这么复杂的配置,并非是发布library最好的方式,想象一下,如果要添加10个library,也需要添加10个url么?这简直是噩梦,所以,为了更好的使用,让我们把library从自己的仓库转移到jcenter。

Part 6 : 同步bintray上的用户仓库到jcenter

同步library到jcenter非常的简单,只需要打开网页点击Add to JCenter。



不需要其他额外操作,点击Send就可以了。



接下来我们什么也不需要做,等待两三个小时,让bintray团队通过我们的请求就可以了。一旦审核通过,你将会收到一封邮件,提示信息有改变。现在让我们回到网页,你可以看到在Linked To部分有所改变。

到现在为止,任何使用jcenter的开发者,只需要一行代码就可以使用我们的library了。

compile 'com.inthecheesefactory.thecheeselibrary:fb-like:0.9.3'

想要在jcenter上查看你的library文件?你可以通过访问http://jcenter.bintray.com,通过library的group id和artifact id来匹配浏览。在这个例子里,应该是:com -> inthecheesefactory -> thecheeselibrary -> fb-like -> 0.9.3。


请注意,链接到jcenter是一次性行为。到现在为止,如果你的包做了任何的修改,例如,上传了新版本的library,删掉了就版本等等。这些改变也会影响到jcenter。所以当你的仓库和jcenter存在差异的时候,你应该花2-3分钟同步这些改变到jcenter。

请注意,如果你决定删掉整个包,放置在jcenter仓库里面的library不会被删除,它们就像僵尸文件一样,没有人可以删除。所以我建议,如果你想要删掉整个包,在移除之前,请先从网站上删掉每一个单独的版本。

Part 7 : 上传library到Maven Central

不是所有的Android开发者都在使用jcenter。还是有一部分开发者在使用mavenCentral(),所以,让我们把library也上传到Maven Central。
为了把library从jcenter提交到Maven Central,有两个前提是需要满足的:
1)二进制包必须已经连接到jcenter
2)Maven Central上的仓库已经批准开放
如果你已经有了这些资格,那么提交library文件到Maven Central也是非常的简单。仅仅需要点击Maven Central连接到包的详细页面。


通过Sonatype的用户名和密码进入页面,点击Sync

如果同步成功,将会显示最新的同步状态,如果失败,也会显示最新的同步失败信息。你必须解决这些问题,因为上传到Maven Central是非常严格的,比如“+”号不能用于版本库依赖关系的定义。
一旦完成,你可以在Maven Central Repository 找到自己的library文件,匹配规则同上,在这个例子中,应该是:com -> inthecheesefactory -> thecheeselibrary -> fb-like -> 0.9.3。

恭喜你,以上就是全部过程,这篇文章很长,但希望对你有用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容