【Android】将aar及其依赖aar上传至maven私有仓库

在上一篇文章里,已经介绍了如何搭建maven私有仓库以及各种仓库的用途:

使用nexus3搭建公司内部的maven私有仓库

本篇文章将介绍如何上传aar,以及每种方式的优劣。

上传aar到maven私有仓库,有两种方式,一种是直接使用nexus3提供的上传功能,另一种是使用gradle脚本上传。

使用nexus3上传aar

【Android】将aar及其依赖aar上传至maven私有仓库_第1张图片
先登录到nexus,点击Upload,选择一个仓库,如上图。
点击Browse会弹出选择文件窗口,选择要上传的aar后,填写其它信息。
Extension是文件拓展名。

主要是填写Group ID、Artifact ID、Version。

这三个参数是maven对组件的基本描述,先介绍一下maven的基本知识,以方便理解后面要讲解的内容。

pom.xml文件

maven是通过pom.xml文件配置项目的各项参数,它是使用xml语言描述的。相当于android中的build.gradle文件。gradle是基于maven改进而来的,maven采用的是xml语言,gradle采用的grovvy语言。gradle比maven更灵活,可读性更强,功能也更强。

先看一下正规的pom.xml文件包含哪些内容,比如google的appcompat的pom.xml文件内容:
【Android】将aar及其依赖aar上传至maven私有仓库_第2张图片
我们依赖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部分。其它信息我们先忽略。

  • Group ID :aar所在组的唯一标识,可以理解为library的分类。一般以xxx.xxx.xxx结构命名。
  • Artifact ID : aar在组内的唯一标识,可以理解为ilbrary的名称。
  • Version :aar的版本。

明白了这三个参数的含义,我们就知道在使用nexus上传aar怎么填入相关信息了。

回到nexus上传aar部分。

记得将这部分勾选,勾选后才会生成pom.xml文件。
在这里插入图片描述
如果没有pom.xml文件,是无法被依赖到项目中。

自动生成pom.xml文件内容:
【Android】将aar及其依赖aar上传至maven私有仓库_第3张图片
使用nexus上传aar的不足:

可以看到上图中自动生成的pom.xml只包含的aar基本信息,不包含其它部分,比如很重要的依赖部分:...,如果aar还依赖其它的aar,那么被依赖的aar是无法自动引入到gradle中的。

使用gradle脚本上传aar

上面说过,使用nexus上传aar,只适合单个aar情况,就是你的aar没有其它的依赖。因为它自动生成的pom.xml文件中,没有depencencies部分,如果你的aar中还依赖了其它aar,那么其它aar是无法加到项目中。所以如果你的aar中还有其它的依赖,比如aar1中依赖了aar2和aar3,那么就必须采用gradle脚本上传。

第一步,在你的library的build.gradle中应用maven插件:
apply plugin: 'com.android.library'
apply plugin: 'maven'  //应用maven插件
第二步,在你的library的build.gradle中添加上传脚本:
//先定义变量
//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
                    }
                }
            }
        }
    }
}
第三步,同步gradle,执行上传命令
./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,demo仅包含3个module,分别是app module,library1,library2。
其中app module仅依赖library1,library1依赖了library2。
demo工程结构:
【Android】将aar及其依赖aar上传至maven私有仓库_第4张图片

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'
}

运行结果如下:
【Android】将aar及其依赖aar上传至maven私有仓库_第5张图片
说明远程依赖是成功的。

注意在上传library时,需要对每个libary执行上传命令:

./gradlew library1:uploadArchives
./gradlew library2:uploadArchives

上传library到maven私有库后,如何依赖到工程,在上一篇文章已经有讲解:
使用nexus3搭建公司内部的maven私有仓库

到nexus服务器查看library1的pom.xml文件内容:
【Android】将aar及其依赖aar上传至maven私有仓库_第6张图片
可以看到自动添加了dependencies部分。

综上,实际上传aar时,建议使用gradle脚本上传会更好,它生成的pom.xml文件内容更全面更丰富。

demo工程代码地址:
https://github.com/devnns/MavenRepoDemo

你可能感兴趣的:(gradle,Android)