在上一篇文章里,已经介绍了如何搭建maven私有仓库以及各种仓库的用途:
使用nexus3搭建公司内部的maven私有仓库
本篇文章将介绍如何上传aar,以及每种方式的优劣。
上传aar到maven私有仓库,有两种方式,一种是直接使用nexus3提供的上传功能,另一种是使用gradle脚本上传。
先登录到nexus,点击Upload,选择一个仓库,如上图。
点击Browse会弹出选择文件窗口,选择要上传的aar后,填写其它信息。
Extension是文件拓展名。
主要是填写Group ID、Artifact ID、Version。
这三个参数是maven对组件的基本描述,先介绍一下maven的基本知识,以方便理解后面要讲解的内容。
maven是通过pom.xml文件配置项目的各项参数,它是使用xml语言描述的。相当于android中的build.gradle文件。gradle是基于maven改进而来的,maven采用的是xml语言,gradle采用的grovvy语言。gradle比maven更灵活,可读性更强,功能也更强。
先看一下正规的pom.xml文件包含哪些内容,比如google的appcompat的pom.xml文件内容:
我们依赖appcompat的时候,只需要在build.gradle中加入这行代码:
implementation 'androidx.appcompat:appcompat:1.0.0'
这样就能下载appcompat这个aar及其依赖的基础aar,那么appcompat是如何将它需要依赖的其它aar引入到项目中的呢?答案就是pom.xml文件。如上图中
标签就是依赖部分的配置。
pom.xml上描述了aar或jar的groupId、artifactId、version、dependencies、developer、license等信息。
implementation 'androidx.appcompat:appcompat:1.0.0'
这行代码中也是按照
groupId:artifactId:version
结构定位aar的。
pom.xml文件中最重要的就是groupId、artifactId、version以及dependency部分。其它信息我们先忽略。
xxx.xxx.xxx
结构命名。明白了这三个参数的含义,我们就知道在使用nexus上传aar怎么填入相关信息了。
回到nexus上传aar部分。
记得将这部分勾选,勾选后才会生成pom.xml文件。
如果没有pom.xml文件,是无法被依赖到项目中。
自动生成pom.xml文件内容:
使用nexus上传aar的不足:
可以看到上图中自动生成的pom.xml只包含的aar基本信息,不包含其它部分,比如很重要的依赖部分:
,如果aar还依赖其它的aar,那么被依赖的aar是无法自动引入到gradle中的。
上面说过,使用nexus上传aar,只适合单个aar情况,就是你的aar没有其它的依赖。因为它自动生成的pom.xml文件中,没有depencencies部分,如果你的aar中还依赖了其它aar,那么其它aar是无法加到项目中。所以如果你的aar中还有其它的依赖,比如aar1中依赖了aar2和aar3,那么就必须采用gradle脚本上传。
apply plugin: 'com.android.library'
apply plugin: 'maven' //应用maven插件
//先定义变量
//basic
def POM_NAME="library1" //aar名称
def POM_VERSION="1.0.0" //aar版本号
def POM_ARTIFACTID="lib1" //artifact ID
def POM_GROUPID="com.devnn.lib" //Group ID
def POM_PACKAGING="aar" //后缀
def POM_DESCRIPTION="lib_one" //描述
//licence
def POM_LICENCE_NAME="The Apache License, Version 2.0"
def POM_LICENCE_URL="http://www.apache.org/licenses/LICENSE-2.0.txt"
def POM_LICENCE_DIST="repo"
//code
def POM_SCM_URL="https://github.com/"
def POM_SCM_CONNECTION="https://github.com/devnns"
def POM_SCM_DEV_CONNECTION="https://github.com/devnns"
//developer
def POM_DEVELOPER_ID="devnn"
def POM_DEVELOPER_NAME="devnn"
//nexues server
def NEXUS_USERNAME="admin" //nexus username
def NEXUS_PASSWORD="123456" //nexus password
def NEXUS_REPOSITORY_URL="http://localhost:8081/nexus3/repository/maven-releases/" //nexus repository url
//上传脚本
uploadArchives {
repositories {
mavenDeployer {
repository(url: NEXUS_REPOSITORY_URL) {
authentication(userName: getRepositoryUserName(), password: getRepositoryPassword())
}
pom.project {
name POM_NAME
version POM_VERSION
artifactId POM_ARTIFACTID
groupId POM_GROUPID
packaging POM_PACKAGING
description POM_DESCRIPTION
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
}
}
}
}
}
}
./gradlew library1:uploadArchives
显示BUILD SUCCESSFUL
说明上传成功。
试想,如果你有多个library,需要上传,library1依赖了library2,library2依赖了library3, app module通过远程依赖library1,library2和library3会自动引入。这个时候在每个library的build.gardle写一遍上传脚本,不太合适吧?
所以我们把上传脚本转移到工程根目录中,单独创建gradle文件,取名为aar_upload.gradle,内容如下:
apply plugin: 'maven'
uploadArchives {
repositories {
mavenDeployer {
repository(url: NEXUS_REPOSITORY_URL) {
authentication(userName: NEXUS_USERNAME, password: NEXUS_USERNAME)
}
pom.project {
name POM_NAME
version POM_VERSION
artifactId POM_ARTIFACTID
groupId POM_GROUPID
packaging POM_PACKAGING
description POM_DESCRIPTION
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
}
}
}
}
}
}
在每个library的build.gradle加上行代码即可:
apply from: '../aar_upload.gradle'
然后把变量定义部分写在各个library的gradle.properties文件(需要创建)中,比如library1的gradle.properties文件内容:
POM_NAME=library1
POM_VERSION=1.1.5
POM_ARTIFACTID=lib1
POM_GROUPID=com.devnn.lib
POM_PACKAGING=aar
POM_DESCRIPTION=lib_one
#licence信息
POM_LICENCE_NAME=The Apache License, Version 2.0
POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt
POM_LICENCE_DIST=repo
#代码库
POM_SCM_URL=https://github.com/
POM_SCM_CONNECTION=https://github.com/devnns
POM_SCM_DEV_CONNECTION=https://github.com/devnns
#开发者信息
POM_DEVELOPER_ID=nannan
POM_DEVELOPER_NAME=nannan
#服务器
NEXUS_USERNAME=admin
NEXUS_PASSWORD=123456
NEXUS_REPOSITORY_URL=http://localhost:8081/nexus3/repository/maven-releases/
笔者写了一个很简单的demo,demo仅包含3个module,分别是app module,library1,library2。
其中app module仅依赖library1,library1依赖了library2。
demo工程结构:
app module中MainActivity代码:
package com.devnn.mavenrepodemo;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import com.devnn.library1.Library1;
public class MainActivity extends AppCompatActivity {
private TextView tvMessage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvMessage = findViewById(R.id.main_text);
tvMessage.setText(Library1.hello());
tvMessage.append("\n");
tvMessage.append(Library1.call());
}
}
library1中只有Library1这个类,代码如下:
package com.devnn.library1;
import com.devnn.library2.Library2;
/**
* create by nannan on 2020/6/10
*/
public class Library1 {
public static String hello(){
return "hello,I am Library1";
}
public static String call(){
return Library2.hello();
}
}
library2中只有Library2这个类,代码如下:
package com.devnn.library2;
/**
* create by nannan on 2020/6/10
*/
public class Library2 {
public static String hello(){
return "hello,I am Library2";
}
}
其中app module通过远程依赖方式依赖library1,而library1远程依赖了library2。
很显然,app module并没有直接依赖library1和library2的源码,并且app module没有直接依赖library2,但是调用了library2中的api。
app module的dependency代码:
dependencies {
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.devnn.lib:lib1:1.1.5'
}
library1的dependency代码:
dependencies {
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'com.devnn.lib:lib2:1.0.1'
}
library2的dependency代码:
dependencies {
implementation 'androidx.appcompat:appcompat:1.0.2'
}
注意在上传library时,需要对每个libary执行上传命令:
./gradlew library1:uploadArchives
./gradlew library2:uploadArchives
上传library到maven私有库后,如何依赖到工程,在上一篇文章已经有讲解:
使用nexus3搭建公司内部的maven私有仓库
到nexus服务器查看library1的pom.xml文件内容:
可以看到自动添加了dependencies部分。
综上,实际上传aar时,建议使用gradle脚本上传会更好,它生成的pom.xml文件内容更全面更丰富。
demo工程代码地址:
https://github.com/devnns/MavenRepoDemo