美文网首页Android TechAndroidStudio集中营Android进阶
如何通过Android Studio发布library到jCen

如何通过Android Studio发布library到jCen

作者: stefanli | 来源:发表于2016-03-19 10:26 被阅读2682次


    在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。

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

    相关文章

      网友评论

      • CPLASF1925:artifactId没有设置的话,默认是项目根目录名称吗
      • jokermoon:请问如果库升级之后,还需要再点击 add to Jcenter 么
      • 汤增雷:谢谢分享,非常适合入门!
      • 黄光华:很强!很好!很棒!!!
      • wanbo_:注册了账号后,界面不一样呢?找不到Maven按钮和 new package
      • 71caf019970b:part4有点儿问题。apply plugin: 'com.github.dcendents.android-maven' 报错这个找不到, project build里面也配置了classpath的。
      • 47287ba8b36e:谢谢分享,写的文章都好详细,非常适合入门
      • Harlan1994:很感谢作者分享,这里有一个问题,我在安装cygwin的时候卡住了,在Cygwin Terminal输入gpg --gen-key命令时,提示没有该命令。是不是我Cygwin安装出问题了,本人初学者,望能解答,谢谢!
        Ulez:在git bash下执行
      • 6ee72519b51d:谢谢作者分享

      本文标题:如何通过Android Studio发布library到jCen

      本文链接:https://www.haomeiwen.com/subject/bushlttx.html