1. 程式人生 > >如何使用Android Studio把自己的Android library分發到jCenter和Maven Central

如何使用Android Studio把自己的Android library分發到jCenter和Maven Central

譯文出自 : 開發技術前線 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大作!