发布library到Maven仓库

Android Studio中想要使用一些第三方类库的时候非常方便,只需要在build.gradle中加入一行代码就可以了: 

dependencies {
    compile 'com.google.code.gson:gson:2.3.1'
}


Eclipse转过来的时候感觉太方便了,也不用下jar包然后拷贝到libs目录了,重要的是以后升级起来灰常方便,改个数字就好了。 那究竟它里面是怎么运转的呢?其实Android Studio是从Maven仓库中下载所配置的libraray

总的来说,Android只有两种存放library的服务器就是jCenterMaven Central:jCenterjCenter

Maven

  • 仓库。你可以在这里查看它所有的

library

  • 。 想要在项目中使用

jCenter

  • 必须要在项目的

build.gradle

  • 中像如下这样进行声明: 
• allprojects {
    repositories {
        jcenter()
    }
}

Maven Central


Maven Central

Maven

  • 仓库。想要在项目中使用

Maven Central

  • 需要在项目的

build.gradle

  • 文件中像下面这样进行声明: 
allprojects {
    repositories {
        mavenCentral()
    }
}

  • 虽然

jCenter

Maven Central

  • 都是

Android

  • 标准的

library maven

  • 仓库,但是他俩是由不同提供者维护,并且存放到完全不同的服务器上,所以他俩之间毫无关系。
    除了这两个标准的服务器外,如果我们使用的

library

  • 作者把该

library

  • 放到自己的服务器上,我们还可以自己定义特有的

Maven

  • 仓库服务器。例如

Twitter

Maven

  • 仓库,如果你想使用

  • 上的

library

  • 你必须要自己定义仓库的

url

repositories {
    maven { url 'https://maven./public' }
}
然后才能正常使用
dependencies {
    compile 'com.crashlytics.sdk.android:crashlytics:2.2.4@aar'
}

上传到自建服务器需要定义仓库的url,所以会比上传到标准的maven仓库使用起来要更麻烦。至于上传到jCenter还是Maven Central上面就要看开发者个人的爱好了,当然在这两个上面都上传是最方便的。在Android Studio开始的几个版本中,它将Maven central 作为默认仓库。新建项目之后build.gradle中会自动生成Maven central仓库的配置。 但是Maven Central最大的问题就是上传library非常困难,同时还会由安全方面的原因,所以后来Android Studio将默认仓库替换成jCenter。所以最近的几个版本中创建项目之后,build.gradle中会默认定义jCenter而不是Maven Central。 jCenter相对Maven Central来说更好的几个主要原因: jCenter

  • 通过

CDN

  • 发送

library

  • ,开发者会由更快的下载体验。

jCenter

  • 作为世界最大的

Java

  • 仓库,所以它上面的

library

  • 会更多。

jCenter

  • 上传

library

  • 更简单,不需要像在

Maven Central

  • 上那么复杂。

jCenter

  • 的用户界面更友好。

jCenter

bintray

  • 网站上可以通过一键实现将

library

  • 上传到

Maven Central

  • 上。

librarybintrayjCenter中然后再一键上传到Maven Central上。 picasso为例认识一下几个主要的部分:

我们在使用picasso时,它会告诉我们按照如下使用: 

compile 'com.squareup.picasso:picasso:2.5.2'


或者


<dependency>
  <groupId>com.squareup.picasso</groupId>
  <artifactId>picasso</artifactId>
  <version>2.5.2</version>
</dependency>


jCenterMaven Central中的使用方法.jCentercom.squareup.picasso就是grounId,通常我们以开发者的报名后面紧跟library的名字来命名groupIdpicassoartifactId,artifactId也就是library真实的名称。,后面的2.5.2就是当前的version.Android StudioMaven服务器上去下载我们所配置的library然后与我们项目一起进行编译。从Maven仓库上下载的是该libraryjar或者aar文件。libraryjaraarjar包大家都知道。那什么是aar呢?aar是在jar的基础上进行开发的,这是因为Androd Library需要植入一些特有的文件,例如资源文件、assetsjni、清单文件等。而这些都不是jar的标准,因为aar就是在jar包的基础上新增了对其他文件的封装。当然他和jar包一样,在本质上都是zip包,下面我们看一下aar的目录结构: 

- /AndroidManifest.xml
- /classes.jar
- /res/
- /R.txt
- /assets/
- /libs/*.jar
- /jni/<abi>/*.so
- /proguard.txt
- /lint.jar


groupIdartifactId以及aar了,那接下来我们就讲一下具体的发布流程了:

androidstudio新建项目build configuration language_android

在Bintray上创建一个包

Maven

  • 后进入。

    androidstudio新建项目build configuration language_maven_02

  • 添加新包。

    androidstudio新建项目build configuration language_maven_03

  • 填写包信息

    androidstudio新建项目build configuration language_android_04

    包名这里对于单词之间要用

-

  • 分割。
  • 然后会提示已经上传。
    到这里我们已经在

bintray

  • 上创建了一个

Maven

  • 仓库,接下来要做的就是上传

library

在Sonatype上传件一个Maven Central账户。

  • 注册Sonatype账号
    Sonatype上注册账号。 注册完登陆后需要在

JIRA

  • 中创建一个

issue

  • ,这样他就会允许你上传匹配

Maven Central

  • 提供的

GROUP_ID

library

  • 。  

    androidstudio新建项目build configuration language_上传_05

     Project: Community Support - Open Source Project Repository Hosting
    Issue Type: New Project
    Summary: 你的 library名称的概要,比如The Cheese Library。
    Group Id: 输入根GROUP_ID,比如, com.charonchui。一旦批准之后,每个以com.charon开始的library都允许被上传到仓库,比如com.charonchui.xxx。
    Project URL: 输入任意一个你想贡献的library的URL,比如, https:///CharonChui/CyberLink4Android
    SCM URL: 版本控制的URL,比如 https:///CharonChui/CyberLink4Android.git
    其他的都不用管,写完之后创建就可以了。 然后就是开始等,大约一周左右就会获准将自己的

library

  • 分享到

Maven Central

  • 下面就是

Bintray

  • 中的账户选项中填写

Sonatype

  • 用户名。 

    androidstudio新建项目build configuration language_maven_06

  • 开启自动注册功能,为了能让我们通过

jcenter

  • 上传的

libraray

  • 自动发布到

Maven Central

  • 中 
  • 使用下面的命令生成一个key。如果是windows用户需要使用cygwin。否则不能执行

gpg --gen-key

  • 创建完成后可以使用

gpg --list-keys

  • 命令来查看创建key的信息. 接下来需要将生成的key上传到keyserver上才能发挥作用。 

    androidstudio新建项目build configuration language_上传_07

    如上图所示将

key

  • 上传到

keyserver

  • 让它发挥作用,运行如下命令,将下面的PUBLIC_KEY_ID替换成上面2048R/后面的数字,如我的是B861C367 

gpg --keyserver hkp:// --send-keys PUBLIC_KEY_ID

  • 运行以下命令 
gpg -a --export yourmail@email.com > public_key_sender.asc
gpg -a --export-secret-key yourmail@email.com > private_key_sender.asc

运行完上面的两个命令后,会在当前目录分别生成public_key_sender.asc以及private_key_sender.ask两个文件,下面我们就打开这两个文件的内容,填写到Bintray的Edit Profile页面中的GPG注册部分。 

androidstudio新建项目build configuration language_android_08

  • 开启自动注册。

Edit Your Profile

  • 页面找到

Repositories

  • 后,选择

maven

  • 后的

edit

  • 。然后将GPG sign uploaded files using Bintray's public/private key pair.打上勾就可以了。 

    androidstudio新建项目build configuration language_上传_09

     

    androidstudio新建项目build configuration language_maven_10

接下来就是如何将Android Studio中的Library Module进行上传

build.gradle文件。如下: 

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        // 注意gradle版本要再1.1.2以上,之前的版本存在问题。如果在工程中/gradle/wrapper/gradle-wrapper.properties重看到当前的gradle版本为2.4,下面的配置版本就要改为1.3.0
        classpath 'com.android.tools.build:gradle:1.2.3'
        // 下面的部分就为新添加的。
        // 用于上传项目到bintray
        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.2'
        // 用于生成javaDoc和jar,如果gradle版本为2.4及以上,下面的版本就要改为1.3,具体可参考https:///dcendents/android-maven-gradle-plugin
        classpath 'com.github.dcendents:android-maven-plugin:1.2'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}


local.properties文件,在里面配置apikey、用户名以及密码,以便bintray进行验证。之所以要把这些东西配置到该文件中是因为这些信息都比较敏感,不能分享到别处,包括版本控制里面。而在创建项目的时候local.properties已经被添加到.gitignore中了,所以这些数据不会被上传:

需要添加如下三行代码: 

bintray.user=YOUR_BINTRAY_USERNAME  // 这里一定要用小写,不要用CharonChui不然会报错的,因为他会根据该用户名去找指定package,如果是大写他就找不到了。
bintray.apikey=YOUR_BINTRAY_API_KEY
bintray.gpg.password=YOUR_GPG_PASSWORD


Api key可以在Binatry官网上面的Edit Profile页面下的API Key中获取。

最后要做的就是修改library module中的build.gradle文件。 下面这是最初的状态: 

apply plugin: 'com.android.library'

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"

    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}


下面就是修改之后的文件: 


apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'
apply plugin: "com.jfrog.bintray"

// This is the library version used when deploying the artifact
version = "1.0.0"

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"

    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

def siteUrl = 'https:///CharonChui/CyberLink4Android'      // Homepage URL of the library
def gitUrl = 'https:///CharonChui/CyberLink4Android.git'   // Git repository URL
group = "com.charonchui.cyberlink"                      // Maven Group ID for the artifact

install {
    repositories.mavenInstaller {
        // This generates POM.xml with proper parameters
        pom {
            project {
                packaging 'aar'

                // Add your description here
                name 'cyberlink-android'
                description = 'CyberLink for Android is a development package for UPnP™ developers on Android development.'
                url siteUrl

                // Set your license
                licenses {
                    license {
                        name 'The Apache Software License, Version 2.0'
                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                    }
                }
                developers {
                    developer {
                        id 'CharonChui'
                        name 'Charon Chui'
                        email 'charon.chui@'
                    }
                }
                scm {
                    connection gitUrl
                    developerConnection gitUrl
                    url siteUrl

                }
            }
        }
    }
}

task sourcesJar(type: Jar) {
    from android.sourceSets.main.java.srcDirs
    classifier = 'sources'
}

task javadoc(type: Javadoc) {
    source = android.sourceSets.main.java.srcDirs
    classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}

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())

// https:///bintray/gradle-bintray-plugin
bintray {
    user = properties.getProperty("bintray.user")
    key = properties.getProperty("bintray.apikey")

    configurations = ['archives']
    pkg {
        repo = "maven"
        // it is the name that appears in bintray when logged
        name = "cyberlink-android"
        websiteUrl = siteUrl
        vcsUrl = gitUrl
        licenses = ["Apache-2.0"]
        publish = true
        version {
            gpg {
                sign = true //Determines whether to GPG sign the files. The default is false
                passphrase = properties.getProperty("bintray.gpg.password") //Optional. The passphrase for GPG signing'
            }
//            mavenCentralSync {
//                sync = true //Optional (true by default). Determines whether to sync the version to Maven Central.
//                user = properties.getProperty("bintray.oss.user") //OSS user token
//                password = properties.getProperty("bintray.oss.password") //OSS user password
//                close = '1' //Optional property. By default the staging repository is closed and artifacts are released to Maven Central. You can optionally turn this behaviour off (by puting 0 as value) and release the version manually.
//            }
        }
    }
}


bintray了,接下来开启Android StudioTerminal中。

  • 检查代码的正确性,以及编译

library

  • 文件(

aar

  • ,

pom

  • 等)。执行如下命令:

./gradlew install

  • 如果提示权限不足就用

chmod 777 gradlew

  • 改下权限就好了,windows下直接运行

gradlew install

  •  正确的话会提示

BUILD SUCCESSFUL

  • 上传编译的文件到

bintray

  • ,使用如下命令:

./gradlew bintrayUpload

  • 成功的话会提示

SUCCESSFUL

  • 接下来到

bintray

  • 上检查一下你得

package

  • 你会在版本区域发现新上传的版本。点击进去就能发现我们上传的

library

  • 文件。

    androidstudio新建项目build configuration language_maven_11

点击该版本进入后可以看到所有的文件目录。

androidstudio新建项目build configuration language_maven_12

library就已经上传了,任何人都可以使用,但是别高兴的太早,因为现在只是上传到了你自己的私人Maven仓库,而不是jCenter上,如果别人使用你library,他必须要先定义仓库的url, 如下: 

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

dependencies {
    compile 'com.charonchui.cyberlink:cyberlink-android:1.0.0'
}


url那么接下来就是怎么将bintray上我们的仓库上传到jCenter中呢?

library同步到jCenter上非常容易。只需要访问bintray,然后点击Add to jCeter然后在新出来的页面直接点击Send即可。 

androidstudio新建项目build configuration language_maven_13

 现在我们就需要等待bintray团队审核我们的请求,一般会在两三个小时左右,如果审核通过,会收到一封邮件通知。通过这一步之后任何开发者都可以不用配置仓库url直接使用了。

想检查一下自己的library是否在jCenter上存在,可以直接访问http://jcenter.bintray.com,然后根据你的groupId直接进入相应的目录查看即可。这里要说一下,这个链接到jCenter是一个只需要做一次的操作,如果以后对你的package做了修改,或者发布新版本等,这些改变会自动同步到jCenter上。同时,如果你要像删除某一个package,但是在jCenter仓库中的library不会被删除。它会一直存在,没法直接删除,因此如果你想要完全删除的时候,最好在移除package之前先在网页上把删除每个版本。 如何通过后也可以在bintray上面看到,这里已经不显示Add to jCenter按钮了,他会直接显示出来jCenter.

androidstudio新建项目build configuration language_android_14

到这里你就可以在项目中直接使用:     


dependencies {
    compile 'com.charonchui.cyberlink:cyberlink-android:1.0.0'
}


但是,我悲剧了。提示失败了,为什么呢?  

androidstudio新建项目build configuration language_上传_15

                  原因就出来library这个module name这里,因为我这里的module那么是library所以它上传之后的路径就是library而不是cyberlink-android:

androidstudio新建项目build configuration language_上传_16

  

所以通过这里能看出来它是使用当前module的名字的。我们只能通过如下方式去使用: 

dependencies {
    compile 'com.charonchui.cyberlink:library:1.0.0'
}


com.charonchui.cyberlink:cyberlink-android:1.0.0的方式,那就将Android Studiolibrary的名字修改为cyberlink-android后重新上传发布吧。

最后一步:上传library到Maven Central 

jCenter。仍然会有一些人在使用Maven Central。因为此我们仍然需要将library上传到Maven Central上。要从jCenter中上传到Maven Central之前需要先完成以下两部分: Bintray

  • 上的

pacage

  • 已经链接到

jCenter

  • .

Maven Central

  • 上的仓库已经认证通过.

libraryMaven Central就非常简单了,只需要在package的详情页面点击Maven Central的链接。 

androidstudio新建项目build configuration language_android_17

 直接进入下一个页面:

androidstudio新建项目build configuration language_android_18

 然后再出来的页面输入Maven Central对应的用户名和密码点击Sync就可以了。上传到Maven Centrallibrary是非常严格的,比如+号是不能在library版本的依赖定义中使用的。

完成之后,你可以在 Maven Central Repository中找到你的library

总结下在使用过程中遇到的错误: 

  • Maven gradle插件与gradle版本要对应好,如下,不要不对应。
• // Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.3.0'
        // 用于上传项目到bintray
        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.2'
        // 用于生成javaDoc和jar
        classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

windows

  • 下执行

gradlew install

  • 编译

javadoc

  • 时会提示

GBK

  • 编码错误,这时候需要修改编译时的编码,具体放狗搜下,当时我改在

mac

  • 上用了,就没解决。
  • 编译生成

javadoc

  • 时提示很多找不到类,不能使用

<br/>

  • 等错误,这里建议在写注释的时候一定要规范,不要使用汉字,而且不要使用

<br/>

<p>

  • 等。