由于自己寫的博客時間較長,可以參考下別人的文章,可以了解更多細節
引言
使用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的右側上有個任務列表。
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