使用Gradle发布Library到JCenter (Updat

作者: SupLuo | 来源:发表于2017-04-06 10:23 被阅读254次

    引言

    使用Android Studio开发的童鞋,相信都使用过远程依赖吧!啥?远程依赖都不懂?

    dependencies {
        compile'com.android.support:support-v4:22.2.1'
    }
    

    在Module的build.gradle中总看过这样的代码吧,如果你是没有,那么我只能说哥们儿,你是猴子请来的。

    上面的引用方式,就可以让我们在工程中使用support-v4包的内容了,等同于当初在Eclipse开发时代引用support-v4包,是不是感觉这样非常酷,一句话就可以导包了。作为程序员,知其然知其所以然是很有必要的,因此我也试着探索,并且发布了自己的远程依赖库,接下来就一起了解这个过程。

    注:网上有很多类似文章,有些实现的形式不一样,但原理终究是一致的,充其量只是穿的马甲不同而已。

    一、简介

    注:大牛可以忽略这一段,其实也可以忽略整篇文章。

    为什么上面使用那行代码之后就可以使用对应的library了,不知道有没有童靴像我最开始那样感到奇怪。其实这个也不是那么神奇,Android Studio根据Module中build.gradle中的定义(也就是类似上面的定义)从Maven仓库服务器上下载了Library到本地,然后提供给工程使用的(不下载到本地,断网了怎么破..你说是不。)。

    Apache Maven是Apache开发的一个工具,提供了用于贡献library的文件服务器。有两个比较标准的Android Library文件服务器:jcenter和maven central。这两个又是啥鬼?我们接着来。
    其实这种概念上的,我也不是特别懂,就粗略的过一下。

    jcenter是一个由bintray.com维护的Maven仓库。
    我们在项目的build.gradle文件中如下定义仓库,就能使用jcenter了:

    allprojects {
      repositories {
        jcenter()   //关键点是这句
        }
    }
    

    Maven Central则是由sonatype.org维护的Maven仓库。

    我们在项目的build.gradle文件中如下定义仓库,就能使用Maven Central了:

    allprojects {
        repositories {
            mavenCentral()  //关键点是这句
        }
    }
    

    注:从上面可以知道,不管是jcenter还是Maven Central,两者都是Maven仓库。

    所以我们发布Library可以选择发布到上面说的两个Maven仓库中,由于诸多原因,本文只关注发布到jcenter仓库中,粗暴直接的原因就是jcenter发布更简单,并且android stduio创建的项目默认也是配置的jcenter,当然还有so on...

    二、gradle如何从仓库上获取library

    知道gradle如何从仓库获取library的规则,才知道如何在上传的时候满足规则。
    我们知道在项目中配置compile 'com.android.support:support-v4:22.2.1'之后就可以使用support-v4包。

    这句话包含两部分,compile是编译的意思,这个不是我们关注的重点,我们关注后面那个值。
    com.android.support:support-v4:22.2.1这句话包含了三个信息点,通过冒号分割,这个格式就是GROUP_ID:ARTIFACT_ID:VERSION。

    • GROUP_ID定义了library的group,group你可以简单理解为分组一样,每个library是属于一个组的,就好比一个文件要保存在一个文件夹中。所以library的GROUP_ID 是可以相同的,都是为了方便管理,比如v4跟v7的关系,都从属于com.android.support。
    • ARTIFACT_ID就是library的真是名字
    • VERSION就是版本号,建议的形式为x.y.z

    gradle就会通过上面这个格式组装出对应的url,然后下载文件,这个url大致可能是http://jcenter.bintray.com/com/android/support/support-v4/22.2.1 (仅供参考)

    三、发布Library

    这个过程,简单粗暴点来讲,就是我们要把我们的工程发布到jcenter代码仓库,所以有些步骤就是显而易见的,我们一步一步来讲。

    1、注册bintray账号

    bintray又是啥鬼?能吃吗?额...前面已经说了,jcenter是由bintray.com维护的Maven仓库,你要用人家的文件服务器,让你注册个账号,这不是理所应当嘛。

    注册过程很简单,这个不用手把手教吧,注意一点就是你可能打不开这个网站,因为你要感谢“国家给你的保护”。

    2、获取Api Key

    注册之后,
    点击右上角,点击“Your Profile”
    接着点Edit
    左侧菜单,点击“API Key”,接着会让你输入你的密码,输入之后,
    点击“Show”即可查看API Key的内容,记住它。

    3、创建自己的工程

    由于我们上传的通常都是一个Library,所以你最好是单独创建一个Library Module,把这个工程打包上传到代码仓库,怎么创建Library Module这个没啥技术含量吧。

    4、配置工程

    这一步非常关键,也有很多小步骤,注意仔细。

    • 配置工程的local.properties

    bintray.user=YOUR_BINTRAY_USERNAME //记住,是bintray账号名,不是bintray账号
    bintray.apikey=YOUR_BINTRAY_API_KEY //第二步获取的那串字符

    • 配置工程的build.gradle
    buildscript {
       ...
        dependencies {
            ...
           //下面两个包是用于上传的插件
            classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.6'    //关键
            classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'  //关键
             ...
        }
    }
    
    • 配置Library Module的build.grade
    apply plugin:'com.github.dcendents.android-maven'
    apply plugin:'com.jfrog.bintray'
    //这句必须要,即使定义了 'def'变量,否则可能导致400错误
    group="xxxx" //上面介绍的GROUP_ID
    //这句最好也要,即使定义了 'def'变量,否则可能导致400错误
    version="xxxx" //上面介绍的VERSION
    
    install{
        repositories.mavenInstaller {
        // 生成pom文件
        pom {
            project {
                packaging 'aar'
                description 'xxxx'  //描述,可不设置此属性
                 name 'xxx' //名字
                 url 'xxxx'     //项目主页地址,如果没有,通常可以使用github项目的地址
                // 设置协议证书,通常就是Apache 2.0开源协议
                 licenses {
                       license {
                           name 'The Apache Software License, Version 2.0'
                           url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                           distribution 'xxxx' //描述,可不设置此属性
                        }
                 }
    
                 //开发者信息
                 developers {
                      developer {
                          id 'xxxxx' //id 这里具体填什么我都不知道,随便填了自己的常用名,这些信息最后都会写入pom文件
                          name 'xxxxx' //名字
                          email 'xxxx' //邮箱
                      }
                 }
    
                //配置相关项目链接
                 scm {
                        connection 'xxxx' //我使用的是项目在github上生成的git地址
                        developerConnection 'xxxx'//我使用的是项目在github上生成的git地址
                        url 'xxxx'//项目地址  我使用的项目在github上的地址
                  }
             }
         }
    }
    }
    
    //生成对应的source.jar
    task sourcesJar(type: Jar) {
        classifier='sources'
    }
    
    //生成java doc文件
    task javadoc(type: Javadoc) {
        source=android.sourceSets.main.java.srcDirs
     classpath+=project.files(android.getBootClasspath().join(File.pathSeparator))
        failOnError=false
    }
    
    //生成对应的javadoc.jar
    task javadocJar(type: Jar,dependsOn: javadoc) {
    classifier='javadoc'
    from javadoc.destinationDir
    }
    
    artifacts{
    //很多童鞋在后面说到的install那一步经常出错,主要原因是因为无法生成java doc,可以把这一步注释,省去doc的生成。
        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="xxxx" //在bintray上的项目名字
            websiteUrl="xxx" //项目地址  我使用的github项目地址
            vcsUrl="xxx" //项目管理地址  我使用的github上对应的git地址
            licenses=["Apache-2.0"]
            publish=true
        }
    }
    
    }
    

    5、发布Library

    1、在Android Studio执行gradlew install命令

    如果终端最终输出BUILD SUCCESSFUL,则说明所有本地文件都生成成功了。

    2、在Android Studio执行gradlew bintrayUpload命令

    如果终端最终输出BUILD SUCCESSFUL,则说明发布成功,这个时候你登陆bintray,应该能够看到刚才发布成功的工程。

    备注:可能有少数童仔输入命令运行的时候,会出现 command not found这样的提示,这个主要是gradle的配置导致的,具体配置可以查一下。这里我说说怎么解决。说白了这个命令就是快速的执行一些gradle task而已,而所有的gradle task 在Android studio的右侧上有个任务列表。

    969AEBB7-1DC6-4F2C-93E9-36156A5DD025.png

    install这个任务在other中,找到双击运行,bintrayUpload任务在publishing中,找到双击运行,这样跟上面输入命令执行的结果是一样的。

    四、发布到Jcenter

    如果上述步骤SUCCESSFUL了,那么恭喜你,你的library已经发布到互联网了,任何人都可以使用了,不过library只是发布到了你个人的Maven仓库中,而不是jcenter上,如果这个时候要使用你的library,则他必须在工程的build.gradle中配置仓库地址:

    repositories {
    maven {
    url 'https://dl.bintray.com/xxx/maven/'
    }
    

    想要不用去定义url的话,那么只需要把library发布到jcenter即可,发布非常简单,点击项目,进入项目详情界面

    点击‘add to jcenter’,然后提交到bintray团队审核,需要等待一定时间,快的话两三个小时,审核通过之后,任何人就可以不用定义地址而使用你的library了。

    五、可能遇到的坑

    发布过程中可能会遇到一些问题,我也是反反复复弄了几次,才发布成功。接下来我们看看可能遇到哪些问题

    • 编码GBK的不可映射字符

    这是因为javadoc生成的时候使用GBK编码,而项目使用的UTF-8编码。

    解决办法:library的buil.gradle文件的根节点中添加如下代码

    javadoc {
        options{
            encoding "UTF-8"
            charSet 'UTF-8'
            author true
            version true
            links "http://docs.oracle.com/javase/7/docs/api"
        }
    }
    
    • HTTP/1.1 401 Unauthorized [message:This resource requires authentication]

    通常是因为bintray的用户名和API Key配置错误了,注意检查,是bintray用户名而不是bintray登陆账号,最初我就写成自己的账号去了。

    • HTTP/1.1 409 Conflict

    该版本已经存在,需要在 bintray 管理界面上删除该版本后才可以再次上传

    • java.net.SocketException: Software caused connection abort: socket write error

    bintray服务器被GFW墙了,你需要翻墙。

    • 忘记关键字了

    这个问题已经记不起错误的关键字了,因为有很多文章都介绍了如何上传Library到jCenter,但是有些文章有些日子了,

    classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.6'   
    classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'  
    

    这两句他们写的可能是1.2,反正就是比1.3小,Android Studio 的2.x之后,gradle版本很高的话,这个必须配置在1.3以上,bintray的plugin也是,反正这里有点模糊了,大致就是因为这个的版本导致的问题。

    - 400错误

    这个是我现在需要强调的一个错误,因为我弄了一个晚上才解决掉,以免大家遇到问题的时候浪费太多无谓的时间。
    问题的大致描述:Maven group, artifact or version defined in the pom file do not match the file path 'xxxxx-unspecified.pom']
    从表面意思来说,是指group artifact 或者 version跟pom文件中定义的不匹配。
    最初我在Library Module的build.gradle文件中是用的如下配置,定义的变量,并且直接使用的变量

    def proj_version = 'xxx'
    def proj_artifact_id = 'xxx'
    def proj_group='xxx'
    

    但是这样定义的时候,必须配置另外两个值:

    // version 最好是与清单文件中定义的一样
    def proj_version = 'xxx'
    //必须与module名字一样
    def proj_artifact_id = 'xxx'
    def proj_group='xxx'
    //这两个变量必须配置,否则就会出现400
    group = proj_group
    version = proj_version
    

    如果本文有帮助到你,请点赞,That's all, thanks! 有其它问题欢迎留言交流。

    PS:由于上面配置较多,可以把配置Library工程的build.gradle里面的内容独立出来,然后在Module的build.gradle中使用apply 命令,这样可以让Library工程的配置清晰一点,详细的所有配置可以见我github上的配置https://github.com/SupLuo/BintrayDeploy

    网上有很多这样的介绍,其实本质的原理是一模一样的。甚至有人还提出了使用apply 远程文件的方式,也就是把配置部分的代码放在互联网上(比如github上)然后apply 加上对应地址即可,详细可见https://github.com/SupLuo/android-library-publish-to-jcenter

    还是那句话,原理一致。

    最近发布Center的帐号注册有点小变化,多了一个组织的概念,因此个人在注册的时候很容易注册成组织帐号,导致在发布的时候会有写小问题,详见:http://www.qingpingshan.com/rjbc/az/179250.html
    http://www.w2bc.com/article/196530

    相关文章

      网友评论

        本文标题:使用Gradle发布Library到JCenter (Updat

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