聲明:文章為原創(chuàng),轉(zhuǎn)載請注明原文地址。
http://www.lxweimin.com/p/b1fe26d5b8c8
文章中代碼部分已上傳到Github,傳送門在文章末尾。
本次的搭建是在ubuntu系統(tǒng)上進(jìn)行的,windows搭建過程類似。
軟件準(zhǔn)備
此次搭建我們用到了JDK及nexus(sonatype的軟件,不是google的手機(jī))
- JDK (我用的版本所1.7.0_76)
- NEXUS (我用的所nexus-2.12.0-01,在官網(wǎng)下載即可,我下載了nexus-2.12.0-01-bundle.zip 去官網(wǎng)下載 )
安裝過程
JDK的安裝 :
這個我就不寫了,一搜一大堆。可參考文章
NEXUS安裝:
- 把下載的nexus-2.12.0-01-bundle.zip放到/usr/local目錄下(你也可以放到其它目錄)
- 為了減去不必用的麻煩,我建議現(xiàn)在開始使用你的su權(quán)限。
命令行:sudo su
會讓你輸入密碼確認(rèn),確認(rèn)后進(jìn)入超級權(quán)限。 - 解壓壓縮文件。
命令行:**unzip nexus-2.12.0-01-bundle.zip **
解壓文件得到 nexus-2.12.0-01文件及sonatype-work文件夾。我們現(xiàn)在只關(guān)心nexus-2.12.0-01文件夾。
- 軟連接
為了操作方便,我們給這個比較長名字的文件夾建個軟連接(好比所Windows的快捷方式),
命令行: ln -s nexus-2.12.0-01 nexus2 - 運行nexus
我們進(jìn)入到nexus2指向的文件夾下
命令行:cd nexus2 **
啟動nexus
命令行:./bin/nexus start**
失敗了,沒運行起來。如圖,好糾結(jié),一面讓我們run as root,一面又不建議我們這樣。
- 設(shè)置RUN_AS_USER=root
那我們按照它的指示設(shè)置RUN_AS_USER=root
命令行:vi ./bin/nexus
vi設(shè)置run_as_root.jpg
VI編輯器不熟悉的話,可以用你熟悉的方式修改,不會不丟人- -!
- 再次運行啟動命令
如果看到命令行提示了Started Nexus OSS,說明我們成功了。
訪問下試試:http://localhost:8081/nexus/ 如圖,我們已經(jīng)成功運行。
我遇到一個情況是這樣的,已經(jīng)提示我“Started Nexus OSS”。但是瀏覽器訪問不到。這時我嘗試再次使用命令啟動nexus。仍然提示我“Started Nexus OSS”。如果你也遇到這種情況就注意了,現(xiàn)在是有問題的,服務(wù)沒起來。如果起來了,再次啟動會提示“Nexus OSS is already running.”我經(jīng)過排查發(fā)現(xiàn)是因為我系統(tǒng)的JAVA環(huán)境不對,沒有裝Oracle的JDK,而是使用了自帶的OpenJDK(具體版本忘了,特別聲明,有的OpenJDK版本是可以讓nexus正常運行的),那你就去裝下Oracle的JDK吧。
配置
- 點擊右上角的"Log In",默認(rèn)用戶名密碼所admin/admin123。
-
登錄后,點擊右側(cè)菜單欄Views/Respositories->Respositories,將會看到下圖幾個倉庫。
默認(rèn)的倉庫-步驟2.jpg - 我們可以看到這些倉庫的類型有:group、hosted、proxy、virtual。
hosted,本地代理倉庫,通常我們會部署自己的構(gòu)件到這一類型的倉庫。
proxy,代理的遠(yuǎn)程倉庫,它們被用來代理遠(yuǎn)程的公共倉庫,如maven中央倉庫。
group,倉庫組,用來合并多個hosted/proxy倉庫,通常我們配置maven依賴倉庫組。
virtual,這種是maven1的,以后基本不會用到或者很少會用到,所以不用過多理會。
我這里并沒有打算講怎么新建倉庫,因為nexus提供的這幾個倉庫對于簡單使用已經(jīng)可以了。
- 下面我們先來配置一下Central倉庫:
a.修改Download Remote Indexes選項為True(允許下載遠(yuǎn)程倉庫的索引)
b.在Central倉庫上右擊,選擇Repair Index(代理倉庫會去下載遠(yuǎn)程倉庫的索引,方便搜索)
c.片刻之后我們在倉庫下方的詳細(xì)信息處點擊Browse Index 可以看到有個文件夾 Central,前方有個加號可以打開,如果沒有信息,說明還沒有下載下來,或者下載失敗了。你可以選擇等一等,或者在最右側(cè)的菜單欄選擇Administration->Logging,查看運行信息,可能對你有幫助。
有的時候你確實需要等一等,因為我遇到過,怎么也沒有索引下載下來,大概我吃了午飯回來,發(fā)現(xiàn)它自己下載好了。
- 同步驟4一樣來配置Apache Snapshots
這里為我們可以看到倉庫policy有Releases、Snapshots兩種。
Snapshot 代表不穩(wěn)定、尚處于開發(fā)中的版本。
Release 代表穩(wěn)定的版本
現(xiàn)在你可以嘗試在右側(cè)菜單欄的搜索框嘗試搜索內(nèi)容。如果你的proxy倉庫成功的下載了索引,我們嘗試搜索okhttp(你也可以換個關(guān)鍵字)你將會看到如下面的畫面
自帶倉庫Releases、Snapshots就是為我們準(zhǔn)備的上傳我們自己lib文件的倉庫,所以就不必新建其它倉庫了
配置倉庫組Public Repositories。如下圖配置好后,千萬要點save進(jìn)行保存。
倉庫組與倉庫就像我們android開發(fā)中ViewGroup 與 View的關(guān)系。本身包含其他倉庫,對外又像倉庫一樣使用。
8.新建SnapShots倉庫組。點擊Add->Repository Group。會在下方倉庫區(qū)新生成一個“New Repository Group”。我們像下方圖: snapshots配置-步驟8.jpg 那樣對它進(jìn)行配置。
使用我們的倉庫
在我們項目的主build.gradle中修改allprojects的maven地址:
allprojects {
repositories {
//jcenter()
maven {url "http://ip:8081/nexus/content/groups/PublicSnapshots/"}
}
}
"sync now"一下,現(xiàn)在我們的工程配置的依賴就已經(jīng)使用我們自己搭建的私有倉庫了。
上圖中Public Snapshots庫對應(yīng)的Respository Path就是我們上方替換默認(rèn)maven庫地址的私庫地址。下面Releases、Snapshots庫地址就是我們下節(jié) 發(fā)布到私服 上傳腳本中自己的lib庫要發(fā)布到的倉庫地址。
發(fā)布到私服
接下來,我們將在Android Studio環(huán)境下,來發(fā)布我們自己的庫文件
1.在我們的工程下新建一個lib,我這就叫l(wèi)ikelib吧。
2.在主項目下新建一個maven_push.gradle來寫我們的發(fā)布到maven庫的腳本
// The Maven plugin adds support for deploying artifacts to Maven repositories.
// 一個可以讓你把庫上傳到maven倉庫的插件
apply plugin: 'maven'
// The signing plugin adds the ability to digitally sign built files and artifacts. These digital signatures can then be used to prove who built the artifact the signature is attached to as well as other information such as when the signature was generated.
// 對庫文件進(jìn)行數(shù)字簽名的插件,可以通過簽名知道誰創(chuàng)建了這個庫文件,簽名的時間等等信息
apply plugin: 'signing'
// 聲明變量記錄maven庫地址
def mavenRepositoryUrl
// 判斷是發(fā)布到正式庫,還是snapshots庫
if (isReleaseBuild()) {
println 'RELEASE BUILD'
// 下面的庫地址指向的是我們私有倉庫的Releases 倉庫
mavenRepositoryUrl = hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL
: "http://IP:8081/nexus/content/repositories/releases/"
} else {
println 'SNAPSHOTS BUILD'
// 下面的庫地址指向的是我們私有倉庫的snapshots 倉庫
mavenRepositoryUrl = hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL
: "http://IP:8081/nexus/content/repositories/snapshots/"
}
// NEXUS_USERNAME等變量在我們主項目的gradle.properties中可以找到
def getRepositoryUsername() {
return hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : ""
}
def getRepositoryPassword() {
return hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : ""
}
// 根據(jù)我們在likelib下gradle.properties中聲明的版本名稱,來分辨是Release版本還是 snapshots版本
def isReleaseBuild() {
return !VERSION_NAME.contains("SNAPSHOT");
}
//"afterEvaluate是什么鳥?你可以理解為在配置階段要結(jié)束,項目評估完會走到這一步。" 引用自http://jiajixin.cn/2015/08/07/gradle-android/
afterEvaluate { project ->
// 我們聲明我們要執(zhí)行的上傳到maven的task
uploadArchives {
repositories {
mavenDeployer {
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
// 我們類比下compile com.squareup.okhttp:okhttp:2.7.0
// artifactId 對應(yīng)com.squareup.okhttp; groupId 對應(yīng)okhttp;version對應(yīng)2.7.0
// 這樣就類似坐標(biāo)的方式定位到了制定的庫文件
pom.artifactId = POM_ARTIFACT_ID
pom.groupId = POM_GROUP_ID
pom.version = VERSION_NAME
// 授權(quán)驗證,這里也就是你登陸搭建的私服服務(wù)器時候的用戶名\密碼
repository(url: mavenRepositoryUrl) {
authentication(userName: getRepositoryUsername(), password: getRepositoryPassword())
}
// 這里是配置我們maven庫需要的pom.xml文件的各個內(nèi)容,具體意思我們在主目錄gradle.properties中解釋
pom.project {
name POM_NAME
packaging POM_PACKAGING
description POM_DESCRIPTION
url POM_URL
scm {
url POM_SCM_URL
connection POM_SCM_CONNECTION
developerConnection POM_SCM_DEV_CONNECTION
}
licenses {
license {
name POM_LICENCE_NAME
url POM_LICENCE_URL
distribution POM_LICENCE_DIST
}
}
developers {
developer {
id POM_DEVELOPER_ID
name POM_DEVELOPER_NAME
}
}
}
}
}
}
// 進(jìn)行數(shù)字簽名
signing {
required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") }
sign configurations.archives
}
// type顯示指定任務(wù)類型或任務(wù), 這里指定要執(zhí)行Javadoc這個task,這個task在gradle中已經(jīng)定義
task androidJavadocs(type: Javadoc) {
// 設(shè)置源碼所在的位置
source = android.sourceSets.main.java.sourceFiles
}
// 生成javadoc.jar
task androidJavadocsJar(type: Jar) {
// 指定文檔名稱
classifier = 'javadoc'
from androidJavadocs.destinationDir
}
// 生成sources.jar
task androidSourcesJar(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.sourceFiles
}
// 產(chǎn)生相關(guān)配置文件的任務(wù)
artifacts {
archives androidSourcesJar
archives androidJavadocsJar
}
}
3.在主項目下gradle.properties中來聲明我們運行腳步時需要的信息
# properties for maven2 repository
# nexus服務(wù)器登陸時候的用戶名/密碼
NEXUS_USERNAME=admin
NEXUS_PASSWORD=admin123
# 在POM文件中使用的group ID
POM_GROUP_ID=com.exmaple.like
# POM文件中指向你網(wǎng)站的地址
POM_URL=https://github.com/achenglike
# SCM是指版本管理工具,一下說他的相關(guān)信息
POM_SCM_URL=https://github.com/
POM_SCM_CONNECTION=https://github.com/achenglike
POM_SCM_DEV_CONNECTION=https://github.com/achenglike
# 你的開放協(xié)議相關(guān)信息
POM_LICENCE_NAME= Apache License Version 2.0
POM_LICENCE_URL= https://github.com/achenglike/Gallery/blob/master/LICENSE
POM_LICENCE_DIST=Apache License Version 2.0
# 開發(fā)者的相關(guān)信息
POM_DEVELOPER_ID=achenglike
POM_DEVELOPER_NAME=achenglike
3.在我們likelib項目下的build.gradle引入我們的腳本
apply from: '../maven_push.gradle'
4.在我們likelib項目下新建一個gradle.properties來存我們需要發(fā)布的版本、格式等信息
# 庫名稱
POM_NAME=Like Library
# artifactId
POM_ARTIFACT_ID=like
# 庫的打包格式為aar, 常見的還有jar
POM_PACKAGING=aar
# 庫的描述,說明他是干啥的
POM_DESCRIPTION=like Library
# 要發(fā)布的版本好,snapshots 版本可以使用格式 1.0.0-SNAPSHOT
VERSION_NAME=1.0.0
5.我們現(xiàn)在可以在android studio的Terminal中來發(fā)布我們的庫文件了 。
輸入命令:gradle uploadArchives
運行結(jié)束Terminal會提示成功或失敗,提示成功說明已經(jīng)上傳到了你的私庫中。
如果沒有意外,我們已經(jīng)發(fā)布到了我們的私有倉庫,我們可以自己去看看,就像下面的圖。
使用
接下來我們將使用我們上傳的庫文件
1.在app 模塊的build.gradle中引入依賴
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.2.0'
compile 'com.android.support:design:23.2.0'
compile 'com.exmaple.like:like:1.0.0'
}
最下面的庫引用就是我們剛才上傳的庫文件
2.我們在app模塊使用依賴的庫
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, Hello.getInstance().hello(), Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
完
文章為原創(chuàng),轉(zhuǎn)載請注明原文地址。
http://www.lxweimin.com/p/b1fe26d5b8c8
示例中的工程已久上傳到了Github