前言
在Android开发中,会经常遇到需要将写好的某个lib用于各个不同的项目中。一般的做法,就是将lib直接导入到项目中。但是假如lib有bug,那么所有使用lib的项目我们都要进去修改lib的bug,这样即繁琐,工作量又大。假如我们可以像gralde中添加依赖那样,直接一句implementation 'xxx'
代码从maven仓库中调用lib,那么我们就不用再一个一个项目中去修复lib的bug了,这样不仅省事了许多,还安全。
正文
一、本地搭建maven私服
- 在
gradle
中添加如下代码,与android{...}
同级
// 添加 maven 插件
apply plugin: 'maven'
uploadArchives {
repositories {
mavenDeployer {
pom.project {
// 自定义的项目分组
groupId 'com.homeprint.lib'
// 自定义项目名称
artifactId 'homeprint-core'
// 项目版本号
version '1.0.1'
}
// 自定义本地仓库路径,此处是项目根目录下的 repo 目录中
repository(url: uri("../repo"))
}
}
}
- 点击
gradle
右上角的Syc Now
,同步一下项目,然后在右侧的项目的gradle
中找到Tasks
中的upload
,双击upload
中的uploadArchives
,将项目发布到本地的maven
仓库中
- 我配置的本地仓库路径是项目根目录的
repo
目录,所以可以看到在项目根目录中出现仓库文件夹
4.如何在项目中引用发布的lib?
- 首先在工程的
build.gradle
(是project
的build.gradle
而不是module
的build.gradle
)中添加我们配置的本地仓库路径。
(注:build.gradle
中有两个repositories
,buildscript
中的是用于gradle
本身构建时使用的,allprojects
中的才是给项目依赖使用的,我们在allprojects
的repositories
中添加本地maven
地址)
- 然后在需要使用的
module
中添加依赖implementation 'com.homeprint.lib:homeprint-core:1.0.0'
,依赖的项目名规则为groupId:artfactId:version
,所以我的依赖为com.homeprint.lib:homeprint-core:1.0.0
这样就完成了,我们就可以肆无忌惮的在需要的项目中引用我们发布的lib啦,但是这个仅限于本地使用,给自己独立开发时提供方便。如果是团队开发,大家使用不同的电脑,就不行了。那么团队开发时,我们想要达到这种效果该怎么做呢?
二、使用Nexus3.x搭建maven私服
1. 下载Nexus3.x
现在Nexus最新版已经是3.x了,个人喜欢使用新版,所以本次我们使用Nexus3.x来搭建maven私服。我们先去官网下载Nexus Repository Manager OSS 3.x,我用的是windows
系统,所以我下载的是windows版本
的
2. Nexus的安装与配置
-
目前最新版是
3.14.0
,将下载的压缩包解压
在减压的文件夹nexus-3.14.0-04-win64
中有两个文件夹nexus-3.14.0-04
和sonatype-work
。nexus-3.14.0-04
是程序,sonatype-work
是工作目录,如果以后要备份数据,只要备份sonatype-work
就行。 将
nexus-3.14.0-04-win64\nexus-3.14.0-04\bin
文件夹所在路径添加到环境变量Path
中,我的路径是D:\software\nexus\nexus-3.14.0-04-win64\nexus-3.14.0-04\bin
-
配置
nexus-3.14.0-04-win64\nexus-3.14.0-04\etc
目录下nexus-default.properties
文件
上述配置中有三个字段关注一下,application-host
、application-port
以及nexus-context-path
application-host :是你访问的nexus服务器的IP,默认为
0.0.0.0
(即只要是本机上的IP,就能连上nexus服务器,详解点我)。为了安全和屏蔽掉其他IP,我们可以改访问IP为localhost指向的IP(一般默认指向127.0.0.1
,可以去C:\Windows\System32\drivers\etc
的hosts
文件中查询localhost指向的IP),改成本机上其他IP也可以application-port:是IP的端口号,默认为
8081
,如果端口号被占用,自行换成其他端口号-
nexus-context-path:上下文对象路径,默认是没有的,如果添加了上下文对象路径,需要在访问地址(访问地址:
application-host:application-port
)后面加上下文对象路径,即访问地址变为:application-host:application-port/nexus-context-path
以下是个人更改后的字段值,当然如果只想简单使用,不更改也没事,可以跳过
application-port=8081
application-host=127.0.0.1
- 打开
CMD
,执行命令nexus.exe /run
- 浏览器中输入:
127.0.0.1:8081
(此处为你配置的application-host:application-port
,如果你也配置了nexus-context-path
,则为application-host:application-port/nexus-context-path
,例:假如我配置nexus-context-path=/test
,浏览器中输入:127.0.0.1:8081/test
),进入nexus管理页面,至此nexus已经安装并且启动成功
3. Nexus的仓库创建
在创建仓库前,先介绍一下仓库的三种存储类型Release
、Snapshot
和Mixed
,创建仓库时会使用到
- Release(正式版): 正式版,适合项目稳定后正式发布使用,特性看下面的原理简介 [important]。
- Snapshot(快照版): 快照版,适合项目在开发调试中使用,特性看下面的原理简介 [important] 。
- Mixed(混合版): 可包含release和snapshot版本
Release
与Snapshot
的原理简介:它们的主要区别在于本地获取这些依赖的机制不同。
- 对于Release版本的项目: 当项目中添加了一个正式版的version为x的依赖时,构建工具在构建项目时会从远程仓库中下载这个version为x的依赖到本地仓库缓存起来,下次再构建项目时,构建工具会从本地仓库中查找是否存在这个version为x的依赖,存在就不会在去远程仓库中拉取。这种特性会导致在团队开发中,如果你发布一个正式版的项目时,仍然使用的是同一个version,就可能出现其他使用这个version项目的成员根本接收不到项目的最新变更,这是糟糕的,为了生命安全,大家尽量不要这么做。所以,在每次发布正式版项目时,必须更新version。
- 对于Snapshot版本的项目: 当项目中添加了一个快照版的version为x的依赖时,不管本地仓库中是否存在这个version为x的依赖,构建工具都会尝试从远程仓库中查看这个version为x的依赖是否最新。这样就能保证团队开发时,所有使用这个version为x的依赖的项目都能获取到依赖最新的变更,而且不用不停的迭代依赖的version。最后一还有一点,Snapshot版项目发布时的version一定要以
-SNAPSHOT
结尾,英文字母必须大写。
下面正式开始仓库创建流程:
- 先登录,初始用户名和密码分别为
admin
和admin123
- 登录后,如下图操作所示,看到有个模块为
Blob Stores
,这是文件存储的地方,默认存在default
中,你可以点击Create blob store
自己创建一个存储点
这里,我自己创建了名为homeprint
的新的存储点
-
创建自己的maven仓库
- 可以看到一共有三种maven类型的仓库供我们选择
-
hosted(宿主仓库) :专门存放无法从远程仓库中下载的构件或者公司内部自主开发的一些构件。当hosted仓库找不到目标构件时,并不能从远程仓库下载。并且想要将内部开发构件上传到maven仓库,三种仓库中只能使用hosted。
-
proxy(代理仓库) : 当用户向proxy请求一个资源时,proxy会先在本地仓库中寻找是否有该资源,没有的话会从远程仓库下载,然后返回给用户;同时会缓存在本地,下次用户再请求相同资源时,就可以直接在本地中找到并返回给用户。proxy起到一层缓存与中转的作用。
proxy代理的远程仓库可以配置,这里我选择阿里云的maven仓库(http://maven.aliyun.com/nexus/content/groups/public/
,因为在国内比中央仓库快很多)
(注意:不支持将内部自主研发的项目上传到proxy上,只能上传到hosted中,proxy的主要作用只是缓存从远程仓库下载的资源和作为中转站去远程仓库下载需要的资源)
-
group(仓库组) :多个仓库的聚合体,将你在nexus中想要使用的maven仓库聚合在一起,对用户暴露统一的地址,这样用户就不需在项目中配置多个maven地址了。(同样也不支持将内部研发项目上传到group中,只能发布到hosted)
- 仓库创建完成(不必要三种仓库都创建,选择你想创建的就行)。点击仓库的
copy
可以拷贝仓库路径。
4. 发布项目到maven仓库
第一种:使用gradle自动发布
在需要发布的module的build.gradle
中加入如下代码,与在第一种在发布到maven仓库的实现基本一致
apply plugin: 'maven'
uploadArchives {
configuration = configurations.archives
repositories {
mavenDeployer {
// 仓库路径(只能是hosted仓库)
repository(url: 'http://192.168.10.128:8081/repository/homeprint-hosted/') {
// 你 Nexus 的账户密码
authentication(userName: 'admin', password: 'admin123')
}
pom.project {
version '1.0.1'
artifactId 'homeprint-common'
groupId 'com.homeprint.lib'
description 'xxxxxx'
}
}
}
}
然后在右侧的双击下图中的uploadArchives
,即可发布上传
上传完成后,可以在仓库中看到发布的项目
第二种:使用网页上传
点击仓库的upload component
可以手动上传,一般现成的jar或者aar文件可以直接选择手动上传
5. module中使用发布的项目
在工程的build.gradle
中添加maven
地址
allprojects {
repositories {
maven { url 'http://127.0.0.1:8081/repository/homeprint-group/' }
}
}
在module的build.gradle
中添加依赖
implementation 'com.homeprint.lib:homeprint-common:1.0.0'
三、其他注意事项
1. gradle中如何指定要上传到maven的文件
// 将项目指定的 _exports 文件夹下的内容打成 jar
task makeJar(type: Jar) {
baseName = "hpauth-exports"
version = "1.0.0"
extension = "jar"
from('build/intermediates/classes/debug/')
from('build/tmp/kotlin-classes/debug/')
include('com/homeprint/module/auth/_exports/**')
destinationDir = file('build/_exports')
}
// 配置需要上传到 maven 仓库的文件,即将上面打包的 jar 上传
artifacts {
archives makeJar
}
// 上传部分仍然与之前相同
uploadArchives {
repositories {
mavenDeployer {
repository(url: 'http://127.0.0.1:8081/repository/maven-snapshots/') {
authentication(userName: 'admin', password: 'admin123')
}
pom.project {
version '1.0.0-SNAPSHOT'
artifactId 'hpauth-exsppt'
groupId 'com.homeprint.module'
description 'xxxxxxx'
}
}
}
}
2. 关于外部设备访问Nexus的问题
上述中,一开始我配置的IP地址是127.0.0.1
,此IP地址外部设备是连接不上的,仅能本机访问。如果要在同一局域网内让外部设备可以访问,请更改为能让外部设备连上的IP地址,例如PC在局域网内被分配到的IPV4地址。详解点我
3. 关于Nexus初始时的默认仓库
nexus在一开始就给我们提供了一些默认仓库
- maven-central:代理仓库,配置的是maven官方2号仓库的地址
- maven-public:仓库组
- maven-releases:宿主仓库,仓库的存储类型为Release
- maven-snapshot:宿主仓库,仓库的存储类型为Snapshot
上述内容中已经对这些仓库的类型介绍过,就不在多说了。这些默认仓库我们是可以直接使用的,基本已经满足我们所有的需求,所以如果不创建仓库,可以直接使用默认仓库。
4. Android开发中常用的maven代理地址
- 阿里云:http://maven.aliyun.com/nexus/content/groups/public/
- google:https://dl.google.com/dl/android/maven2/
- jcenter:https://jcenter.bintray.com/
- mavenCentral:https://repo.maven.apache.org/maven2/
- jitpack:https://jitpack.io
以上几个基本就是android开发中常用的几个maven仓库了,其中阿里云是国内仓库,其他是国外仓库。国内仓库的优势在于下载速度快,毕竟祖国伟大的网络对于国外的网络不怎么友好。但是国内仓库可能更新会比国外仓库慢一点。出于以上考虑,我们可以将以上仓库都集成在group仓库组中,一定要将阿里云放在其他国外maven仓库的上面,因为访问仓库时的顺序是从上往下访问的,这样就既有了国内仓库的速度,又可以在国内仓库没有资源时,去国外仓库获取到资源。
5. Nexus中用户的权限管理
团队开发的时候,为了避免散发超级管理员权限,可以根据每个成员的实际情况,给他们配置用户角色和权限。
-
Security -> Privileges: 所有的权限都放在了这里
-
Security -> Roles: 角色管理界面,可在此界面创建角色
-
Security -> Users: 用户管理界面,可在此界面创建用户
-
Security -> Anonymous: 匿名用户管理界面(即游客管理),这里有个注意的地方,如下图中,有个
Allow anonymous users to access the server
,游客默认是有浏览
和读取仓库
的权限的,如果取消勾选,则游客没有任何权限。
6. 如何从Nexus中下载jar包或者aar包
四、如何实现在外网中访问自己的maven仓库
- 将项目上传到
Github
、码云
或者类似的管理平台中,通过jitpack
发布(最简单的方式) - 将项目发布到
jcenter
或者mavenCentral
中,这个比第一种复杂一些,如果要使用jcenter
发布,可以使用bintray-release
插件 - 将
Nexus
部署到阿里云或者其他云服务器中,这时使用的版本不再是Windows
版而是Unix
版 - 以上都是常用的方法,因为时间关系就不再详细介绍了,大家可以自行百度。最后介绍一种取巧的方法,就是找一些可以将内网IP映射到外网访问的小工具,比如
nat123
、花生壳
之类的,这里我用的是windows_386
,一共就三个文件
其中a.bat
是运行文件,里面就一行代码如下:
ngrok -config=ngrok.cfg -subdomain my 8080
其中my
为域名的前缀,8080
为端口号,这两样是可以根据需要,自行修改的。双击a.bat
文件开始运行程序,结果如下:
ngrok (Ctrl+C to quit)
Tunnel Status online
Version 1.7/1.7
Forwarding http://my.tunnel.qydev.com -> 127.0.0.1:8080
Forwarding https://my.tunnel.qydev.com -> 127.0.0.1:8080
Web Interface 127.0.0.1:4040
# Conn 0
Avg Conn Time 0.00ms
当 Tunnel Status
为online
时,代表已经将内网IP映射到公网上,映射的IP为127.0.0.1
(不可变),端口号为你在a.bat
中配置的端口号,此处为8080
(可配置)。与IP绑定的域名为my.tunnel.qydev.com
,其中前缀my
即为你在a.bat
中配置的前缀。这样你在浏览器中输入my.tunnel.qydev.com
就可以连上本机的127.0.0.1:8080
。然后,将nexus的IP和端口号分别配置为127.0.0.1
和8080
就可以在外网访问到本机上的Nexus了。这种方式很简单,成本低,但是访问速度有点慢,但是谁还没有个不在公司coding的时候,这时候就可以提供点便利了。