Android gradle发布aar包到maven私服

2,611 阅读2分钟

作用

将原本放在${project_home}/libs的依赖包去除,在build.gradle中的dependencies中添加implementation、compile导入依赖,可以缩减项目大小

怎么做

在library的build.gradle中添加uploadArchives task,具体代码如下

uploadArchives {
    repositories.mavenDeployer {
        pom.groupId = 'com.xxx.xxx'
        pom.artifactId = 'xxx'
        pom.version = '1.2.3'
        //pom.version = '1.2.3-SNAPSHOT'
        repository(url: '${maven release url}') {
            authentication(userName: '${username}', password: '${password}')
        }
        snapshotRepository(url: '${maven snapshot url}') {
            authentication(userName: '${username}', password: '${password}')
        }
    }
}

执行./gradlew uploadArchives即可上传至远程maven仓库

解释

  • groupId("公司网站的倒序")、artifactId("包名")、version("版本号x.x.x")按顺序填入
  • version的命名带有"SNAPSHOT"后缀,则使用snapshotRepository指定的地址,不过不带该后缀,则使用repository指定的地址
  • SNAPSHOT版本专门用于调试过程中,频繁改变,每次上传的aar带有当前日期的后缀,依赖使用时,直接在版本后添加"-SNAPSHOT",不需要填具体的包路径
  • 如果没有远程仓库,可以在本地试验,${maven release url}直接改成testmaven,注意不要带"/",testmaven/就会报错,这是个坑;直接运行./gradlew uploadArchives发现本地生成了testmaven文件夹,并包括aar包

怎么使用上传后的包

在主项目的build.gradle中添加

repositories {
    maven {
        url "${maven release url}"
    }
}
implementation '${groupId}:${artifactId}:${version}'

上传前先检查版本是否重复

/////////////////////////////////
// 检查提交版本是否重复
/////////////////////////////////
uploadArchives {
    String mavenUrl = "http:xxx"
    String groupId = "xxx.xxx.xxx"
    String artifactId = "xxx"
    String userName = "xxx"
    String password = "xxx"
    String version = "xxx"
    repositories.mavenDeployer {
        repository(url: mavenUrl) {
            authentication(userName: userName, password: password)
            pom.groupId = groupId
            pom.artifactId = artifactId
            String meta_data_url = mavenUrl + pom.groupId.replace(".", "/") + "/" + pom.artifactId + "/maven-metadata.xml"
            println("checkPath: " + meta_data_url)
            checkHasOldMaven(groupId, artifactId, meta_data_url, version)
            pom.version = version
            println("upload finish")
        }
    }
}

static def isNumericZidai(String str) {
    for (int i = 0; i < str.length(); i++) {
        if (!Character.isDigit(str.charAt(i))) {
            return false
        }
    }
    return true
}

def checkHasOldMaven(String groupId, String artifectId, String urlStr, String newVersion) {
    println("检测maven上是否存在相同版本的库:" + project.name)

    if (newVersion == null) {
        throw new IllegalStateException("输入版本不能为空!")
    }

    String[] ss = newVersion.split("\\.")
    if (ss.length != 3) {
        throw new IllegalStateException("版本号必须是三段,每段用'.'隔开!且必须是数字")
    }

    for (String str : ss) {
        if (!isNumericZidai(str)) {
            throw new IllegalStateException("非法的版本号: " + newVersion + ";版本号每段都必须由数字组成!")
        }
    }

    def tipsMsg = ""
    boolean hasOldMavenVersion = false
    try {
        URL url = new URL(urlStr)
        HttpURLConnection conn = (HttpURLConnection) url.openConnection()
        conn.setConnectTimeout(3 * 1000)
        InputStream inputStream = conn.getInputStream()
        XmlParser xmlParser = new XmlParser()
        def metadata = xmlParser.parse(inputStream)
        NodeList groupIdNode = metadata.getAt("groupId")
        NodeList artifactIdNode = metadata.getAt("artifactId")
        println("groupId:" + groupIdNode.get(0).text())
        println("artifectId: " + artifactIdNode.get(0).text())


        String remoteG = groupIdNode.get(0).text()
        String remoteA = artifactIdNode.get(0).text()


        if (groupId.equals(remoteG) && artifectId.equals(remoteA)) {
            NodeList nodeList = metadata.get("versioning")

            NodeList allList = nodeList.getAt("versions")

//            println allList

            if (allList != null && allList.size() > 0) {
                NodeList versons = allList.getAt("version")
//                println versons
                boolean find = false
                if (versons != null && versons.size() > 0) {
                    for (Node node : versons) {
                        println(node.text())
                        if (newVersion == node.text()) {
                            hasOldMavenVersion = true
                            find = true
                        }
                    }
                }
                if (find) {
                    println("库中已经存在相同的版本,请修改版本号 重新提交!" + newVersion)
                }
            }

            NodeList list = nodeList.getAt("latest")
            if (list == null || list.size() == 0) {
                list = nodeList.getAt("release")
            }
            Node node = list.get(0)
            String latestVersion = node.text()

            println("maven最新版本为:" + latestVersion)
            println("待上传的版本为:" + newVersion)

            String[] ns = newVersion.split("\\.")
            String[] ls = latestVersion.split("\\.")

            int nsr = 0
            int lsr = 0

            boolean nvl = false

            // 从高位比较版本号,如果高位相同则比较下一位
            int i = 0
            int j = 0
            println("i " + i + " " + j)
            for (; i < ns.length && j < ls.length;) {
                nsr = Integer.valueOf(ns[i])
                lsr = Integer.valueOf(ls[j])
                i++
                j++
                println(nsr + "  " + lsr)
                if (nsr > lsr) {
                    break
                } else if (lsr > nsr) {
                    nvl = true
                    break
                }
            }

            println "版本差异:" + nsr + " " + lsr

            if (nvl) {
                hasOldMavenVersion = true
                tipsMsg = "待提交版本号必须大于库中的最新版本号!待提交版本:${newVersion},maven库中最新版本${latestVersion}"
            }

            if (newVersion == latestVersion) {
                hasOldMavenVersion = true
            }
        } else {
            return
        }
    } catch (Exception e) {
        e.printStackTrace()
        if (e instanceof FileNotFoundException) { // 跳过初次创建
            hasOldMavenVersion = false
        } else {
            hasOldMavenVersion = true
        }
    }
    if (hasOldMavenVersion) {
        if (tipsMsg == "") {
            tipsMsg = "maven上已经存在与待提交版本(" + newVersion + ")相同版本的库,请提升版本后重新提交,避免同一个版本对应多套代码!"
        }
        throw new IllegalStateException(tipsMsg)
    }
}

一些想法

maven私服是Android的外围知识,属于负责开发的工具,掌握一次可以一劳永逸,同样Jenkins也属于这一类,针对这类工具,我对自己的要求是熟练会用,这次的maven研究,主要做了私服的搭建、aar包的上传、下载、snapshot版的使用,包括翻阅了gradle关于maven依赖的源码,主要是为了确认snapshot的依赖规则,这是看的同事翻阅源码才想起来的