如何使用Android Studio把自己的Android library分發到jCenter和Maven Central
阿新 • • 發佈:2019-01-05
譯文出自 : 開發技術前線 www.devtf.cn與 泡在網上的日子http://www.jcodecraeer.com/
譯者 : jianghejie
如果你想在Android Studio中引入一個library到你的專案,你只需新增如下的一行程式碼到模組的build.gradle檔案中。
dependencies {
compile 'com.inthecheesefactory.thecheeselibrary:fb-like:0.9.3'
}
就是如此簡單的一行程式碼,你就可以使用這個library了。
酷呆了。不過你可能很好奇Android Studio是從哪裡得到這個library的。這篇文章將詳細講解這是怎麼回事,包括如何把你的庫釋出出去分享給世界各地的其他開發者,這樣不僅可以讓世界更美好,還可以耍一次酷。
Android studio 是從哪裡得到庫的?
先從這個簡單的問題開始,我相信不是每個人都完全明白Android studio 是從哪裡得到這些library的。莫非就是Android studio 從google搜尋然後下載了一個合適的給我們?
呵呵,沒那麼複雜。Android Studio是從build.gradle裡面定義的Maven 倉庫伺服器上下載library的。Apache Maven是Apache開發的一個工具,提供了用於貢獻library的檔案伺服器。總的來說,只有兩個標準的Android library檔案伺服器:jcenter 和 Maven Central。
jcenter
jcenter是一個由 bintray.com維護的Maven倉庫 。你可以在這裡看到整個倉庫的內容。
我們在專案的build.gradle 檔案中如下定義倉庫,就能使用jcenter了:
allprojects {
repositories {
jcenter()
}
}
Maven Central
Maven Central 則是由sonatype.org維護的Maven倉庫。你可以在這裡看到整個倉庫。
注:不管是jcenter還是Maven Central ,兩者都是Maven倉庫
我們在專案的build.gradle 檔案中如下定義倉庫,就能使用Maven Central了:
allprojects {
repositories {
mavenCentral()
}
}
注意,雖然jcenter和Maven Central 都是標準的 android library倉庫,但是它們維護在完全不同的伺服器上,由不同的人提供內容,兩者之間毫無關係。在jcenter上有的可能 Maven Central 上沒有,反之亦然。
除了兩個標準的伺服器之外,如果我們使用的library的作者是把該library放在自己的伺服器上,我們還可以自己定義特有的Maven倉庫伺服器。Twitter的Fabric.io 就是這種情況,它們在https://maven.fabric.io/public上維護了一個自己的Maven倉庫。如果你想使用Fabric.io的library,你必須自己如下定義倉庫的url。
repositories {
maven { url 'https://maven.fabric.io/public' }
}
然後在裡面使用相同的方法獲取一個library。
dependencies {
compile 'com.crashlytics.sdk.android:crashlytics: [email protected]'
}
但是將library上傳到標準的伺服器與自建伺服器,哪種方法更好呢?當然是前者。如果將我們的library公開,其他開發者除了一行定義依賴名的程式碼之外不需要定義任何東西。因此這篇文章中,我們將只關注對開發者更友好的jcenter 和 Maven Central 。
實際上可以在Android Studio上使用的除了Maven 倉庫之外還有另外一種倉庫:Ivy 倉庫 。但是根據我的經驗來看,我還沒看到任何人用過它,包括我,因此本文就直接忽略了。
理解jcenter和Maven Central
為何有兩個標準的倉庫?
事實上兩個倉庫都具有相同的使命:提供Java或者Android 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上也極有可能有。換句話說jcenter是Maven Central的超集。
- 上傳library到倉庫很簡單,不需要像在 Maven Central上做很多複雜的事情。
- 友好的使用者介面
- 如果你想把library上傳到 Maven Central ,你可以在bintray網站上直接點選一個按鈕就能實現。
基於上面的原因以及我自己的經驗,可以說替換到jcenter是明智之舉。
所以我們這篇文章將把重心放在jcenter,反正如果你能成功把library放在jcenter,轉到 Maven Central 是非常容易的事情。
gradle是如何從倉庫上獲取一個library的?
在討論如何上傳library到jcenter之前,我們先看看gradle是如何從倉庫獲取library的。比如我們在 build.gradle輸入如下程式碼的時候,這些庫是如果奇蹟般下載到我們的專案中的。
compile 'com.inthecheesefactory.thecheeselibrary:fb-like:0.9.3'
一般來說,我們需要知道library的字串形式,包含3部分
GROUP_ID:ARTIFACT_ID:VERSION
上面的例子中,GROUP_ID是com.inthecheesefactory.thecheeselibrary ,ARTIFACT_ID是fb-like,VERSION是0.9.3。
GROUP_ID定義了library的group。有可能在同樣的上下文中存在多個不同功能的library。如果library具有相同的group,那麼它們將共享一個GROUP_ID。通常我們以開發者包名緊跟著library的group名稱來命名,比如com.squareup.picasso。然後ARTIFACT_ID中是library的真實名稱。至於VERSION,就是版本號而已,雖然可以是任意文字,但是我建議設定為x.y.z的形式,如果喜歡還可以加上beta這樣的字尾。
下面是Square 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是否存在,如果是,gradle會獲得請求library的路徑,一般這個路徑都是這樣的形式:GROUP_ID/ARTIFACT_ID/VERSION_ID。比如可以在http://jcenter.bintray.com/com/squareup/otto/1.3.7和https://oss.sonatype.org/content/repositories/releases/com/squareup/otto/1.3.7/
下獲得com.squareup:otto:1.3.7的library檔案。
然後Android Studio 將下載這些檔案到我們的電腦上,與我們的專案一起編譯。整個過程就是這麼簡單,一點都不復雜。
我相信你應該清楚的知道從倉庫上下載的library只是儲存在倉庫伺服器上的jar 或者aar檔案而已。有點類似於自己去下載這些檔案,拷貝然後和專案一起編譯。但是使用gradle依賴管理的最大好處是你除了新增幾行文字之外啥也不做。library一下子就可以在專案中使用了。
瞭解aar檔案
等等,我剛才說了倉庫中儲存的有兩種型別的library:jar 和 aar。jar檔案大家都知道,但是什麼是aar檔案呢?
aar檔案時在jar檔案之上開發的。之所以有它是因為有些Android Library需要植入一些安卓特有的檔案,比如AndroidManifest.xml,資原始檔,Assets或者JNI。這些都不是jar檔案的標準。
因此aar檔案就時發明出來包含所有這些東西的。總的來說它和jar一樣只是普通的zip檔案,不過具有不同的檔案結構。jar檔案以classes.jar的名字被嵌入到aar檔案中。其餘的檔案羅列如下:
/AndroidManifest.xml (mandatory)
/classes.jar (mandatory)
/res/ (mandatory)
/R.txt (mandatory)
/assets/ (optional)
/libs/*.jar (optional)
/jni//*.so (optional)
/proguard.txt (optional)
/lint.jar (optional) 可以看到.aar檔案是專門為安卓設計的。因此這篇文章將教你如何建立與上傳一個aar形式的library。
如何上傳library到jcenter
我相信你已經知道了倉庫系統的大體工作原理。現在我們來開始最重要的部分:上傳。這個任務和如何上傳library檔案到http://jcenter.bintray.com一樣簡單。如果做到,這個library就算髮布了。好吧,有兩個需要考慮:如何建立aar檔案以及如何上傳構建的檔案到倉庫。
雖然需要若干步驟,但是我還是想強調這事並不複雜,因為已經準備好了所有事情。整個過程如下圖:
因為細節比較多,我分為7部分,一步一步的詳細解釋清楚。
第一部分:在bintray上建立package
首先,你需要在bintray上建立一個package。為此,你需要一個bintray賬號,並在網站上建立一個package。
第一步:在bintray.com上註冊一個賬號。(註冊過程很簡單,自己完成)
第二步:完成註冊之後,登入網站,然後點選maven。
blob.png
第三步:點選Add New Package,為我們的library建立一個新的package。
maven2
第四步:輸入所有需要的資訊
maven3
雖然如何命名包名沒有什麼限定,但是也有一定規範。所有字母應該為小寫,單詞之間用-分割,比如,fb-like。
當每項都填完之後,點選Create Package。
第五步:網頁將引導你到 Package編輯頁面。點選 Edit Package文字下的Package名字,進入Package詳情介面。
maven4
完工!現在你有了自己在Bintray上的Maven倉庫,可以準備上傳library到上面了。
maven5
Bintray賬戶的註冊就完成了。下一步是Sonatype,Maven Central 的提供者。
第二部分:為Maven Central建立個Sonatype帳號
注:如果你不打算把library上傳到Maven Central,可以跳過第二和第三部分。不過我建議你不要跳過,因為仍然有許多開發者在使用這個倉庫。
和jcenter一樣,如果你想通過Maven Central,貢獻自己的library,你需要在提供者的網站Sonatype上註冊一個帳號。
你需要知道的就是這個帳號,你需要在Sonatype網站上建立一個IRA Issue Tracker 帳號。請到Sonatype Dashboard 註冊這個帳號。
完成之後。你需要請求得到貢獻library到Maven Central的許可權。不過這個過程對我來說有點無厘頭,因為你需要做的就是在JIRA中建立一個issue,讓它們允許你上傳匹配Maven Central提供的GROUP_ID的library。
要建立上述所講到的issue,訪問Sonatype Dashboard,用建立的帳號登入。然後點選頂部選單的Create。
填寫如下資訊:
Project: Community Support - Open Source Project Repository Hosting
Issue Type: New Project
Summary: 你的 library名稱的概要,比如The Cheese Library。
Group Id: 輸入根GROUP_ID,比如,com.inthecheeselibrary 。一旦批准之後,每個以com.inthecheeselibrary開始的library都允許被上傳到倉庫,比如com.inthecheeselibrary.somelib。
Project URL: 輸入任意一個你想貢獻的library的URL,比如, https://github.com/nuuneoi/FBLikeAndroid。
SCM URL: 版本控制的URL,比如 https://github.com/nuuneoi/FBLikeAndroid.git。
其餘的不用管,然後點選Create。現在是最難的部分...耐心等待...平均大概1周左右,你會獲准把自己的library分享到 Maven Central。
最後一件事是在Bintray Profile的帳戶選項中填寫自己的Sonatype OSS使用者名稱。
sonatypeusername
點選Update,完成。
第三部分:啟用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 < [email protected]>
sub 2048R/98765432 2015-03-07
現在你需要把key上傳到keyserver讓它發揮作用。為此,請呼叫如下的命令並且將其中的PUBLIC_KEY_ID替換成上面pub一行中2048R/ 後面的 8位16進位制值,譬如本例是01ABCDEF。
gpg --keyserver hkp://pool.sks-keyservers.net --send-keys PUBLIC_KEY_ID
然後,使用如下的命令以ASCII形式匯出公共和私有的key,請將[email protected]替換成你前面用於建立key的email。
gpg -a --export [email protected] > public_key_sender.asc
gpg -a --export-secret-key [email protected] > private_key_sender.asc
開啟Bintray的Edit Profile頁面點選GPG 註冊。分別在Public Key和 Private Key中填入上一步匯出的public_key_sender.asc和 private_key_sender.asc檔案中的內容。
1434992443352430.png
點選Update儲存這些key。
最後一步就是啟用自動註冊。到Bintray的主頁點選maven。 blob.png
點選編輯 blob.png
勾選中GPG Sign uploaed files automatically以啟用自動註冊。
blob.png
點選Update儲存這些步驟。完成。現在只需點選一下,每個上傳到我們Maven倉庫的東西都會自動註冊並做好轉向Maven Central 。
請注意這是一次性的操作,以後建立的每一個library都要應用此操作。
Bintray和Maven Central 已經準備好了。現在轉到Android Studio部分。
第四部分:準備一個Android Studio專案
很多情況下,我們需要同時上傳一個以上的library到倉庫,也可能不需要上傳東西。因此我建議最好將每部分分成一個Module。最好分成兩個module,一個Application Module一個Library Module。Application Module用於展示庫的用法,Library Module是library的原始碼。如果你的專案有一個以上的library,儘管建立另外的module:1個 module對應1 個library。 blob.png
我相信大家知道如何建立一個新的module,因此就不會深入講解這個問題了。其實很簡單,基本就是選擇creating an Android Library module ,然後就完了。
blob.png
下一步是把bintray外掛應用在專案中。我們需要修改專案的build.gradle檔案中的依賴部分,如下:
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.2'
classpath 'com.github.dcendents:android-maven-plugin:1.2'
}
有一點非常重要,那就是gradle build tools的版本設定成1.1.2以上,因為以前的版本有嚴重的bug,我們將使用的是最新的版本1.2.3。
接下來我們將修改local.properties。在裡面定義api key的使用者名稱以及被建立key的密碼,用於bintray的認證。之所以要把這些東西放在這個檔案是因為這些資訊時比較敏感的,不應該到處分享,包括版本控制裡面。幸運的是在建立專案的時候local.properties檔案就已經被新增到.gitignore了。因此這些敏感資料不會被誤傳到git伺服器。
下面是要新增的三行程式碼:
bintray.user=YOUR_BINTRAY_USERNAME
bintray.apikey=YOUR_BINTRAY_API_KEY
bintray.gpg.password=YOUR_GPG_PASSWORD
bintray username 放在第一行, API Key放在第二行, API Key可以在Edit Profile頁面的API Key 選項卡中找到。
最後一行是建立 GPG key的密碼。儲存並關閉這個檔案。
最後要修改的是module的build.gradle檔案。注意前面修改的是專案的build.gradle檔案。開啟它,在apply plugin: 'com.android.library'之後新增這幾行,如下:
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 = '[email protected]'
licenseName = 'The Apache Software License, Version 2.0'
licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
allLicenses = ["Apache-2.0"]
}
bintrayRepo使用預設的,即maven。bintrayName修改成你上面建立的 package name。其餘的項也修改成和你library資訊相匹配的值。有了上面的指令碼,每個人都能通過下面的一行gradle指令碼使用這個library。
compile 'com.inthecheesefactory.thecheeselibrary:fb-like:0.9.3'
最後在檔案的後面追加兩行如下的程式碼來應用兩個指令碼,用於構建library檔案和上傳檔案到bintray(為了方便,我直接使用了github上連線到相關檔案的連結):
apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
完成!你的專案現在設定好了,準備上傳到bintray吧!
第五部分:把library上傳到你的bintray空間
現在是上傳library到你自己的bintray倉庫上的時候了。請到Android Studio的終端(Terminal)選項卡。
terminal
第一步是檢查程式碼的正確性,以及編譯library檔案(aar,pom等等),輸入下面的命令:
> gradlew install
如果沒有什麼問題,會顯示:
BUILD SUCCESSFUL
現在我們已經成功一半了。下一步是上傳編譯的檔案到bintray,使用如下的命令:
gradlew bintrayUpload
如果顯示如下你就大喊一聲eureka吧!
SUCCESSFUL
在bintray的網頁上檢查一下你的package。你會發現在版本區域的變化。
blob.png
點選進去,進入Files選項卡,你會看見那裡有我們所上傳的library檔案。
blob.png
恭喜,你的library終於放在了網際網路上,任何人都可以使用了!
不過也別高興過頭,library現在仍然只是在你自己的Maven倉庫,而不是在jcenter上。如果有人想使用你的library,他必須定義倉庫的url,如下:
repositories {
maven {
url 'https://dl.bintray.com/nuuneoi/maven/'
}
}
...
dependencies {
compile 'com.inthecheesefactory.thecheeselibrary:fb-like:0.9.3'
}
譯者注:前面都沒怎麼看懂,看到上面的程式碼之後一下子全懂了,呵呵。
你可以在bintray的web介面找到自己Maven倉庫的url,或者直接吧nuuneoi替換成你的bintray使用者名稱(因為前面部分其實都是一樣的)。我還建議你直接訪問那個連結,看看裡面到底是什麼。
但是,就如我們前面所講的那樣,讓開發者去定義url這種複雜的事情並不是分享library的最佳方式。想象一下,使用10個library不得新增10個url?所以為了更好的體驗,我們把library從自己的倉庫傳到jcenter上。
第六部分:同步bintray使用者倉庫到jcenter
把library同步到jcenter非常容易。只需訪問網頁並點選Add to JCenter
blob.png
什麼也不做直接點選Send。
blob.png
現在我們所能做的就是等待bintray團隊稽核我們的請求,大概2-3個小時。一旦同步的請求稽核通過,你會收到一封確認此更改的郵件。現在我們去網頁上確認,你會在 Linked To 部分看到一些變化。
blob.png
從此之後,任何開發者都可以使用jcenter() repository 外加一行gradle指令碼來使用我們的library了
compile 'com.inthecheesefactory.thecheeselibrary:fb-like:0.9.3'
想檢查一下自己的library在jcenter上是否存在?你可以直接訪問http://jcenter.bintray.com,然後進入和你library的group id 以及artifact id匹配的目錄。在本例中就是com -> inthecheesefactory -> thecheeselibrary -> fb-like -> 0.9.3。
blob.png
請注意連結到jcenter是一個只需做一次的操作。如果你對你的package做了任何修改,比如上傳了一個新版本的binary,刪除了舊版本的binary等等,這些改變也會影響到jcenter。不過畢竟你自己的倉庫和jcenter在不同的地方,所以需要等待2-3分鐘讓jcenter同步這些修改。
同時注意,如果你決定刪除整個package,放在jcenter倉庫上的library不會被刪除。它們會像殭屍一樣的存在,沒有人再能刪除它了。因此我建議,如果你想刪除整個package,請在移除package之前先在網頁上刪除每一個版本。
第七部分:上傳library到Maven Central
並不是每個安卓開發者都使用jcenter。仍然有部分開發者還在使用mavenCentral() ,因此讓我們也把library上傳到Maven Central 吧。
要從jcenter到Maven Central,首先需要完成兩個任務:
1) Bintray package 已經連線到jcenter。
2) Maven Central上的倉庫已經認證通過
如果你已經通過了這些授權,上傳library package到Maven Central就異常簡單了,只需在package的詳情頁面點選Maven Central 的連結。
syncmavencentral
輸入你的Sonatype使用者名稱和密碼並點選Sync。
syncmavencentral2
如果成功,在Last Sync Status中會顯示Successfully synced and closed repo(見圖),但是如果遇到任何問題,則會在Last Sync Errors顯示出來。你需要根據情況修復問題,能上傳到Maven Central 的library的條件是相當嚴格的,比如+ 號是不能在ibrary版本的依賴定義中使用的。
完成之後,你可以在 Maven Central Repository 上找到你的library。在那些匹配你ibrary的group id以及artifact id的目錄中。比如本例中就是com -> inthecheesefactory -> thecheeselibrary -> fb-like -> 0.9.3。
恭喜!雖然需要許多步驟,但是每一步都很簡單。而且大部分操作都是一勞永逸的。
如此長篇的文章!希望對你有所幫助。我的英語也許有點晦澀,不過希望至少內容是可以理解的。
期待能在上面看到你的library大作!
譯者 : jianghejie
如果你想在Android Studio中引入一個library到你的專案,你只需新增如下的一行程式碼到模組的build.gradle檔案中。
dependencies {
compile 'com.inthecheesefactory.thecheeselibrary:fb-like:0.9.3'
}
就是如此簡單的一行程式碼,你就可以使用這個library了。
酷呆了。不過你可能很好奇Android Studio是從哪裡得到這個library的。這篇文章將詳細講解這是怎麼回事,包括如何把你的庫釋出出去分享給世界各地的其他開發者,這樣不僅可以讓世界更美好,還可以耍一次酷。
Android studio 是從哪裡得到庫的?
先從這個簡單的問題開始,我相信不是每個人都完全明白Android studio 是從哪裡得到這些library的。莫非就是Android studio 從google搜尋然後下載了一個合適的給我們?
呵呵,沒那麼複雜。Android Studio是從build.gradle裡面定義的Maven 倉庫伺服器上下載library的。Apache Maven是Apache開發的一個工具,提供了用於貢獻library的檔案伺服器。總的來說,只有兩個標準的Android library檔案伺服器:jcenter 和 Maven Central。
jcenter
jcenter是一個由 bintray.com維護的Maven倉庫 。你可以在這裡看到整個倉庫的內容。
我們在專案的build.gradle 檔案中如下定義倉庫,就能使用jcenter了:
allprojects {
repositories {
jcenter()
}
}
Maven Central
Maven Central 則是由sonatype.org維護的Maven倉庫。你可以在這裡看到整個倉庫。
注:不管是jcenter還是Maven Central ,兩者都是Maven倉庫
我們在專案的build.gradle 檔案中如下定義倉庫,就能使用Maven Central了:
allprojects {
repositories {
mavenCentral()
}
}
注意,雖然jcenter和Maven Central 都是標準的 android library倉庫,但是它們維護在完全不同的伺服器上,由不同的人提供內容,兩者之間毫無關係。在jcenter上有的可能 Maven Central 上沒有,反之亦然。
除了兩個標準的伺服器之外,如果我們使用的library的作者是把該library放在自己的伺服器上,我們還可以自己定義特有的Maven倉庫伺服器。Twitter的Fabric.io 就是這種情況,它們在https://maven.fabric.io/public上維護了一個自己的Maven倉庫。如果你想使用Fabric.io的library,你必須自己如下定義倉庫的url。
repositories {
maven { url 'https://maven.fabric.io/public' }
}
然後在裡面使用相同的方法獲取一個library。
dependencies {
compile 'com.crashlytics.sdk.android:crashlytics:
}
但是將library上傳到標準的伺服器與自建伺服器,哪種方法更好呢?當然是前者。如果將我們的library公開,其他開發者除了一行定義依賴名的程式碼之外不需要定義任何東西。因此這篇文章中,我們將只關注對開發者更友好的jcenter 和 Maven Central 。
實際上可以在Android Studio上使用的除了Maven 倉庫之外還有另外一種倉庫:Ivy 倉庫 。但是根據我的經驗來看,我還沒看到任何人用過它,包括我,因此本文就直接忽略了。
理解jcenter和Maven Central
為何有兩個標準的倉庫?
事實上兩個倉庫都具有相同的使命:提供Java或者Android 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上也極有可能有。換句話說jcenter是Maven Central的超集。
- 上傳library到倉庫很簡單,不需要像在 Maven Central上做很多複雜的事情。
- 友好的使用者介面
- 如果你想把library上傳到 Maven Central ,你可以在bintray網站上直接點選一個按鈕就能實現。
基於上面的原因以及我自己的經驗,可以說替換到jcenter是明智之舉。
所以我們這篇文章將把重心放在jcenter,反正如果你能成功把library放在jcenter,轉到 Maven Central 是非常容易的事情。
gradle是如何從倉庫上獲取一個library的?
在討論如何上傳library到jcenter之前,我們先看看gradle是如何從倉庫獲取library的。比如我們在 build.gradle輸入如下程式碼的時候,這些庫是如果奇蹟般下載到我們的專案中的。
compile 'com.inthecheesefactory.thecheeselibrary:fb-like:0.9.3'
一般來說,我們需要知道library的字串形式,包含3部分
GROUP_ID:ARTIFACT_ID:VERSION
上面的例子中,GROUP_ID是com.inthecheesefactory.thecheeselibrary ,ARTIFACT_ID是fb-like,VERSION是0.9.3。
GROUP_ID定義了library的group。有可能在同樣的上下文中存在多個不同功能的library。如果library具有相同的group,那麼它們將共享一個GROUP_ID。通常我們以開發者包名緊跟著library的group名稱來命名,比如com.squareup.picasso。然後ARTIFACT_ID中是library的真實名稱。至於VERSION,就是版本號而已,雖然可以是任意文字,但是我建議設定為x.y.z的形式,如果喜歡還可以加上beta這樣的字尾。
下面是Square 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是否存在,如果是,gradle會獲得請求library的路徑,一般這個路徑都是這樣的形式:GROUP_ID/ARTIFACT_ID/VERSION_ID。比如可以在http://jcenter.bintray.com/com/squareup/otto/1.3.7和https://oss.sonatype.org/content/repositories/releases/com/squareup/otto/1.3.7/
下獲得com.squareup:otto:1.3.7的library檔案。
然後Android Studio 將下載這些檔案到我們的電腦上,與我們的專案一起編譯。整個過程就是這麼簡單,一點都不復雜。
我相信你應該清楚的知道從倉庫上下載的library只是儲存在倉庫伺服器上的jar 或者aar檔案而已。有點類似於自己去下載這些檔案,拷貝然後和專案一起編譯。但是使用gradle依賴管理的最大好處是你除了新增幾行文字之外啥也不做。library一下子就可以在專案中使用了。
瞭解aar檔案
等等,我剛才說了倉庫中儲存的有兩種型別的library:jar 和 aar。jar檔案大家都知道,但是什麼是aar檔案呢?
aar檔案時在jar檔案之上開發的。之所以有它是因為有些Android Library需要植入一些安卓特有的檔案,比如AndroidManifest.xml,資原始檔,Assets或者JNI。這些都不是jar檔案的標準。
因此aar檔案就時發明出來包含所有這些東西的。總的來說它和jar一樣只是普通的zip檔案,不過具有不同的檔案結構。jar檔案以classes.jar的名字被嵌入到aar檔案中。其餘的檔案羅列如下:
/AndroidManifest.xml (mandatory)
/classes.jar (mandatory)
/res/ (mandatory)
/R.txt (mandatory)
/assets/ (optional)
/libs/*.jar (optional)
/jni//*.so (optional)
/proguard.txt (optional)
/lint.jar (optional) 可以看到.aar檔案是專門為安卓設計的。因此這篇文章將教你如何建立與上傳一個aar形式的library。
如何上傳library到jcenter
我相信你已經知道了倉庫系統的大體工作原理。現在我們來開始最重要的部分:上傳。這個任務和如何上傳library檔案到http://jcenter.bintray.com一樣簡單。如果做到,這個library就算髮布了。好吧,有兩個需要考慮:如何建立aar檔案以及如何上傳構建的檔案到倉庫。
雖然需要若干步驟,但是我還是想強調這事並不複雜,因為已經準備好了所有事情。整個過程如下圖:
因為細節比較多,我分為7部分,一步一步的詳細解釋清楚。
第一部分:在bintray上建立package
首先,你需要在bintray上建立一個package。為此,你需要一個bintray賬號,並在網站上建立一個package。
第一步:在bintray.com上註冊一個賬號。(註冊過程很簡單,自己完成)
第二步:完成註冊之後,登入網站,然後點選maven。
blob.png
第三步:點選Add New Package,為我們的library建立一個新的package。
maven2
第四步:輸入所有需要的資訊
maven3
雖然如何命名包名沒有什麼限定,但是也有一定規範。所有字母應該為小寫,單詞之間用-分割,比如,fb-like。
當每項都填完之後,點選Create Package。
第五步:網頁將引導你到 Package編輯頁面。點選 Edit Package文字下的Package名字,進入Package詳情介面。
maven4
完工!現在你有了自己在Bintray上的Maven倉庫,可以準備上傳library到上面了。
maven5
Bintray賬戶的註冊就完成了。下一步是Sonatype,Maven Central 的提供者。
第二部分:為Maven Central建立個Sonatype帳號
注:如果你不打算把library上傳到Maven Central,可以跳過第二和第三部分。不過我建議你不要跳過,因為仍然有許多開發者在使用這個倉庫。
和jcenter一樣,如果你想通過Maven Central,貢獻自己的library,你需要在提供者的網站Sonatype上註冊一個帳號。
你需要知道的就是這個帳號,你需要在Sonatype網站上建立一個IRA Issue Tracker 帳號。請到Sonatype Dashboard 註冊這個帳號。
完成之後。你需要請求得到貢獻library到Maven Central的許可權。不過這個過程對我來說有點無厘頭,因為你需要做的就是在JIRA中建立一個issue,讓它們允許你上傳匹配Maven Central提供的GROUP_ID的library。
要建立上述所講到的issue,訪問Sonatype Dashboard,用建立的帳號登入。然後點選頂部選單的Create。
填寫如下資訊:
Project: Community Support - Open Source Project Repository Hosting
Issue Type: New Project
Summary: 你的 library名稱的概要,比如The Cheese Library。
Group Id: 輸入根GROUP_ID,比如,com.inthecheeselibrary 。一旦批准之後,每個以com.inthecheeselibrary開始的library都允許被上傳到倉庫,比如com.inthecheeselibrary.somelib。
Project URL: 輸入任意一個你想貢獻的library的URL,比如, https://github.com/nuuneoi/FBLikeAndroid。
SCM URL: 版本控制的URL,比如 https://github.com/nuuneoi/FBLikeAndroid.git。
其餘的不用管,然後點選Create。現在是最難的部分...耐心等待...平均大概1周左右,你會獲准把自己的library分享到 Maven Central。
最後一件事是在Bintray Profile的帳戶選項中填寫自己的Sonatype OSS使用者名稱。
sonatypeusername
點選Update,完成。
第三部分:啟用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 <
sub 2048R/98765432 2015-03-07
現在你需要把key上傳到keyserver讓它發揮作用。為此,請呼叫如下的命令並且將其中的PUBLIC_KEY_ID替換成上面pub一行中2048R/ 後面的 8位16進位制值,譬如本例是01ABCDEF。
gpg --keyserver hkp://pool.sks-keyservers.net --send-keys PUBLIC_KEY_ID
然後,使用如下的命令以ASCII形式匯出公共和私有的key,請將[email protected]替換成你前面用於建立key的email。
gpg -a --export
gpg -a --export-secret-key [email protected] > private_key_sender.asc
開啟Bintray的Edit Profile頁面點選GPG 註冊。分別在Public Key和 Private Key中填入上一步匯出的public_key_sender.asc和 private_key_sender.asc檔案中的內容。
1434992443352430.png
點選Update儲存這些key。
最後一步就是啟用自動註冊。到Bintray的主頁點選maven。 blob.png
點選編輯 blob.png
勾選中GPG Sign uploaed files automatically以啟用自動註冊。
blob.png
點選Update儲存這些步驟。完成。現在只需點選一下,每個上傳到我們Maven倉庫的東西都會自動註冊並做好轉向Maven Central 。
請注意這是一次性的操作,以後建立的每一個library都要應用此操作。
Bintray和Maven Central 已經準備好了。現在轉到Android Studio部分。
第四部分:準備一個Android Studio專案
很多情況下,我們需要同時上傳一個以上的library到倉庫,也可能不需要上傳東西。因此我建議最好將每部分分成一個Module。最好分成兩個module,一個Application Module一個Library Module。Application Module用於展示庫的用法,Library Module是library的原始碼。如果你的專案有一個以上的library,儘管建立另外的module:1個 module對應1 個library。 blob.png
我相信大家知道如何建立一個新的module,因此就不會深入講解這個問題了。其實很簡單,基本就是選擇creating an Android Library module ,然後就完了。
blob.png
下一步是把bintray外掛應用在專案中。我們需要修改專案的build.gradle檔案中的依賴部分,如下:
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.2'
classpath 'com.github.dcendents:android-maven-plugin:1.2'
}
有一點非常重要,那就是gradle build tools的版本設定成1.1.2以上,因為以前的版本有嚴重的bug,我們將使用的是最新的版本1.2.3。
接下來我們將修改local.properties。在裡面定義api key的使用者名稱以及被建立key的密碼,用於bintray的認證。之所以要把這些東西放在這個檔案是因為這些資訊時比較敏感的,不應該到處分享,包括版本控制裡面。幸運的是在建立專案的時候local.properties檔案就已經被新增到.gitignore了。因此這些敏感資料不會被誤傳到git伺服器。
下面是要新增的三行程式碼:
bintray.user=YOUR_BINTRAY_USERNAME
bintray.apikey=YOUR_BINTRAY_API_KEY
bintray.gpg.password=YOUR_GPG_PASSWORD
bintray username 放在第一行, API Key放在第二行, API Key可以在Edit Profile頁面的API Key 選項卡中找到。
最後一行是建立 GPG key的密碼。儲存並關閉這個檔案。
最後要修改的是module的build.gradle檔案。注意前面修改的是專案的build.gradle檔案。開啟它,在apply plugin: 'com.android.library'之後新增這幾行,如下:
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 = '[email protected]'
licenseName = 'The Apache Software License, Version 2.0'
licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
allLicenses = ["Apache-2.0"]
}
bintrayRepo使用預設的,即maven。bintrayName修改成你上面建立的 package name。其餘的項也修改成和你library資訊相匹配的值。有了上面的指令碼,每個人都能通過下面的一行gradle指令碼使用這個library。
compile 'com.inthecheesefactory.thecheeselibrary:fb-like:0.9.3'
最後在檔案的後面追加兩行如下的程式碼來應用兩個指令碼,用於構建library檔案和上傳檔案到bintray(為了方便,我直接使用了github上連線到相關檔案的連結):
apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
完成!你的專案現在設定好了,準備上傳到bintray吧!
第五部分:把library上傳到你的bintray空間
現在是上傳library到你自己的bintray倉庫上的時候了。請到Android Studio的終端(Terminal)選項卡。
terminal
第一步是檢查程式碼的正確性,以及編譯library檔案(aar,pom等等),輸入下面的命令:
> gradlew install
如果沒有什麼問題,會顯示:
BUILD SUCCESSFUL
現在我們已經成功一半了。下一步是上傳編譯的檔案到bintray,使用如下的命令:
gradlew bintrayUpload
如果顯示如下你就大喊一聲eureka吧!
SUCCESSFUL
在bintray的網頁上檢查一下你的package。你會發現在版本區域的變化。
blob.png
點選進去,進入Files選項卡,你會看見那裡有我們所上傳的library檔案。
blob.png
恭喜,你的library終於放在了網際網路上,任何人都可以使用了!
不過也別高興過頭,library現在仍然只是在你自己的Maven倉庫,而不是在jcenter上。如果有人想使用你的library,他必須定義倉庫的url,如下:
repositories {
maven {
url 'https://dl.bintray.com/nuuneoi/maven/'
}
}
...
dependencies {
compile 'com.inthecheesefactory.thecheeselibrary:fb-like:0.9.3'
}
譯者注:前面都沒怎麼看懂,看到上面的程式碼之後一下子全懂了,呵呵。
你可以在bintray的web介面找到自己Maven倉庫的url,或者直接吧nuuneoi替換成你的bintray使用者名稱(因為前面部分其實都是一樣的)。我還建議你直接訪問那個連結,看看裡面到底是什麼。
但是,就如我們前面所講的那樣,讓開發者去定義url這種複雜的事情並不是分享library的最佳方式。想象一下,使用10個library不得新增10個url?所以為了更好的體驗,我們把library從自己的倉庫傳到jcenter上。
第六部分:同步bintray使用者倉庫到jcenter
把library同步到jcenter非常容易。只需訪問網頁並點選Add to JCenter
blob.png
什麼也不做直接點選Send。
blob.png
現在我們所能做的就是等待bintray團隊稽核我們的請求,大概2-3個小時。一旦同步的請求稽核通過,你會收到一封確認此更改的郵件。現在我們去網頁上確認,你會在 Linked To 部分看到一些變化。
blob.png
從此之後,任何開發者都可以使用jcenter() repository 外加一行gradle指令碼來使用我們的library了
compile 'com.inthecheesefactory.thecheeselibrary:fb-like:0.9.3'
想檢查一下自己的library在jcenter上是否存在?你可以直接訪問http://jcenter.bintray.com,然後進入和你library的group id 以及artifact id匹配的目錄。在本例中就是com -> inthecheesefactory -> thecheeselibrary -> fb-like -> 0.9.3。
blob.png
請注意連結到jcenter是一個只需做一次的操作。如果你對你的package做了任何修改,比如上傳了一個新版本的binary,刪除了舊版本的binary等等,這些改變也會影響到jcenter。不過畢竟你自己的倉庫和jcenter在不同的地方,所以需要等待2-3分鐘讓jcenter同步這些修改。
同時注意,如果你決定刪除整個package,放在jcenter倉庫上的library不會被刪除。它們會像殭屍一樣的存在,沒有人再能刪除它了。因此我建議,如果你想刪除整個package,請在移除package之前先在網頁上刪除每一個版本。
第七部分:上傳library到Maven Central
並不是每個安卓開發者都使用jcenter。仍然有部分開發者還在使用mavenCentral() ,因此讓我們也把library上傳到Maven Central 吧。
要從jcenter到Maven Central,首先需要完成兩個任務:
1) Bintray package 已經連線到jcenter。
2) Maven Central上的倉庫已經認證通過
如果你已經通過了這些授權,上傳library package到Maven Central就異常簡單了,只需在package的詳情頁面點選Maven Central 的連結。
syncmavencentral
輸入你的Sonatype使用者名稱和密碼並點選Sync。
syncmavencentral2
如果成功,在Last Sync Status中會顯示Successfully synced and closed repo(見圖),但是如果遇到任何問題,則會在Last Sync Errors顯示出來。你需要根據情況修復問題,能上傳到Maven Central 的library的條件是相當嚴格的,比如+ 號是不能在ibrary版本的依賴定義中使用的。
完成之後,你可以在 Maven Central Repository 上找到你的library。在那些匹配你ibrary的group id以及artifact id的目錄中。比如本例中就是com -> inthecheesefactory -> thecheeselibrary -> fb-like -> 0.9.3。
恭喜!雖然需要許多步驟,但是每一步都很簡單。而且大部分操作都是一勞永逸的。
如此長篇的文章!希望對你有所幫助。我的英語也許有點晦澀,不過希望至少內容是可以理解的。
期待能在上面看到你的library大作!