Maven 是 Apache 下的一个纯 Java 开发的开源项目,基于项目对象模型(缩写:POM)概念,Maven能够从中央信息管理一个项目的构建、报告和文档等步骤。Maven 也可被用于构建和管理各类项目,例如 C#,Ruby,Scala 和其余语言编写的项目。html
POM(Project Object Model)即项目对象模型,经过xml格式保存的pom.xml文件,做用相似ant的build.xml文件,功能更强大。该文件用于管理:源代码、配置文件、开发者的信息和角色、问题追踪系统、组织信息、项目受权、项目的url、项目的依赖关系等等;node
Glide:POM举个栗子android
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.bumptech.glide</groupId>
<artifactId>glide</artifactId>
<version>4.12.0</version>
<packaging>aar</packaging>
<name>Glide</name>
<description>A fast and efficient image loading library for Android focused on smooth scrolling.</description>
<url>https://github.com/bumptech/glide</url>
...
</project>
复制代码
groupId
: 组织标识,例如:com.github.bumptech.glide,在目录下,将是: com/github/bumptech/glide目录。artifactId
: 项目名称,例如:Glide。version
: 版本号。packaging
: 打包的格式,能够为:pom , jar , maven-plugin , ejb , war , ear , rar , par ,aar等。Maven 仓库能帮助咱们管理构件(主要是JAR),它就是放置全部JAR文件(WAR,ZIP,POM,AAR等等)的地方。git
举个栗子:阿里&jcenter& maven 仓库github
Android引入仓库 : 根 build.gradle配置 gradle—docapache
buildscript {
repositories {
jcenter()
google()
}
}
allprojects {
addRepos(repositories)
repositories{
jcenter()
google()
mavenLocal()
mavenCentral()
maven { url "http://maven.aliyun.com/nexus/content/groups/public" }
maven { url "file:///${rootProject.getRootDir()}/asdk" }
maven { url "file:///${rootProject.getRootDir()}/bsdk" }
}
}
复制代码
buildscript
{ }:Configures the build script classpath for this project.vim
allprojects
{ }:Configures this project and each of its sub-projects.api
注解:buildscript
是gradle脚本执行所需依赖,allprojects
是项目自己须要的依赖,因此咱们将本身所须要的仓库加到allprojects配置中安全
经过以上咱们知道,打包sdk 须要一个托管的仓库,那么下面咱们就介绍一下,如何搭建一个私有仓库;基于安全考虑不用公共仓库,学习一下如何搭建私有仓库。bash
Nexus 简介:是Maven仓库管理器,若是你使用Maven,你能够从Maven中央仓库 下载所须要的构件(artifact)
简介2:World’s #1 Repository Manager(本身夸本身世界第一,其余吹牛逼的不用看了)Single source of truth for all of your components, binaries, and build artifacts Efficiently distribute parts and containers to developers Deployed at more than 100,000 organizations globally
搭建Maven私有仓库步骤
~ » /Users/caining/Documents/applications/nexus-3.28.1-01-mac/nexus-3.28.1-01/bin/nexus start
Starting nexus
复制代码
cd /Users/caining/Documents/applications/nexus-3.28.1-01-mac/nexus-3.28.1-01/etc
vim nexus-default.properties
###########################配置以下
# Jetty section
application-port=8081
application-host=0.0.0.0
复制代码
nexus 2 的默认帐号密码 admin:默认密码admin123登陆; nexus 3第一次启动后 nexus3 会自动生成admin 的密码,存在admin.password
查看密码
~ » vim /Users/caining/Documents/applications/nexus-3.28.1-01-mac/sonatype-work/nexus3/admin.password
复制代码
3866aa0a-39e2-4e14-90bb-4a31c6c303e1
~ » /Users/caining/Documents/applications/nexus-3.28.1-01-mac/nexus-3.28.1-01/bin/nexus stop
Shutting down nexus
Stopped.
复制代码
1、在工程下新建 maven-push.gradle 脚本
apply plugin: 'maven'
uploadArchives {
repository(url: maven.address) { authentication(userName: maven.username, password: maven.password) }
pom.groupId = maven.MAVENGROUPID
pom.artifactId = ARTIFACT
pom.version = maven.appLibVersion
pom.packaging = 'aar'
pom.project {
licenses {
license {
name 'The Apache Software License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
}
}
复制代码
2、配置根gralde配置
1.新建 config.gradle
2.apply from: 'config.gradle'
3.
ext {
maven = [
address : "http://localhost:8081/repository/maven-releases/",//maven 仓库地址
username : "admin",
password : "123456",
appLibVersion : "1.0.6",//打包版本号
buildMAVEN : true ,//是否打开upload功能,为宿主工程准备、、最小侵入宿主工程
MAVENGROUPID : "com.cnn.sdk"//打包groupId 这里统一设置,如须要不一样,请module中单独设置
]
}
复制代码
三 、gradle ext 是什么?
4、module 子 gradle.properties 增长artifact名字
5、sdk-module 子 build.gradle 增长配置
try {
if (maven.buildMAVEN){//这里是true 在宿主工程里,会访问不到而报错
apply from: '../maven-push.gradle'
}
}catch (all){
}
复制代码
以上,执行 uploadArchives task 就会打包并upload 到仓库
> Task :module01:uploadArchives
> Task :module02:writeReleaseAarMetadata
> Task :module02:bundleReleaseAar
> Task :module02:uploadArchives
Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.5/userguide/command_line_interface.html#sec:command_line_warnings
BUILD SUCCESSFUL in 781ms
43 actionable tasks: 41 executed, 2 up-to-date
10:46:48 AM: Task execution finished 'uploadArchives'.
复制代码
Module01 添加依赖implementation project(path: ':module02'),这时候再执行uploadArchives。
重点:抛出问题:若是模块间依赖,以上脚本在全量打包时会报错 以下
缘由:module01 依赖是本地包,因此报错
如何解决?
问题 :填坑对于有互相依赖的包如何处理?对于关联依赖 sdk 如何一键 build 并上传Maven仓库
以上存在的问题 :以上脚本虽然初步完成了sdk 打包并上传Maven仓库,但有问题存在,加入sdk 子module 关联依赖时,子包不发布,主包没法打包成功,那么除了手动一步一步上传外,有没有办法一键上传?
优化思路:动态替换打包后groupId 和 version(因为是动态替换,这里的工程moudle 的名称应该与gradle.properties配置的artifact 保持一致)
关键脚本以下:
pom.withXml {
def childs = asNode().children()
childs.each {
child ->
print("childName->"+child.name().toString()+"\n")
if (child.name().toString().contains('dependencies')) {
child.children().each {
print("dependencies->"+it.text().toString()+"\n")
if (it.text().toString().contains("unspecified")) {
def iterator = it.children().iterator()
def remove = false
while (iterator.hasNext()) {
def node = iterator.next()
if (node.name().toString().contains('groupId')) {
iterator.remove()
}
if (node.name().toString().contains('version')) {
iterator.remove()
remove = true
}
}
if (remove) {
it.appendNode('version', maven.appLibVersion)
it.appendNode('groupId', maven.MAVENGROUPID)
}
print("\n return ->"+it.text().toString()+"\n")
}
}
}
}
}
复制代码
引入方式也很简单
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "groupId:artifactId:version"//此处对应上传的maven 仓库的信息
}
复制代码
经过仓库引入的第三方sdk 在宿主工程里调试,很不方便,虽然能够断电,但源码没法修改,使得在宿主程序中,遇到问题,查问题时,很是不方便,那么有没有好的办法,在本地开发时,不使用仓库包,而是直接引用源码呢?上线时,经过修改配置,引用远程仓库。
咱们知道android module引入模块,是在settings.gradle中,以下:
include ':sdka'
复制代码
宿主根gradle.properties 增长控制参数boolean useLocalLib = true/false
经过settings.gradle配置动态控制是否使用仓库
if (useLocalLib.toBoolean()){
print("sdk调试使用,线上环境忽略如下内容")
include(':module01')
include(':module02')
print("path---->"+getRootDir().getParent())
project(':module01').projectDir = new File(getRootDir().getParent(),"/MavenPackage/module01")
project(':module02').projectDir = new File(getRootDir().getParent(),"/MavenPackage/module02")
}
复制代码
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
if (useLocalLib.toBoolean())
implementation project(":module01")
else
implementation 'com.cnn.sdk:module01:1.0.0'
}
复制代码
以上,能够在宿主工程里,经过参数userLocalSDK,达到引入sdk源码的目的,源码并不在宿主git 下;完成优雅的调试sdk 的目的。
经过Maven仓库引入的好处:组件隔离,业务隔离,减小侵入等
使用Nexus搭建Maven 私有仓库,以及经常使用命令 初始密码等,以及使用
经过gradle plugin: 'maven' 打包并upload to Maven Repository
宿主工程引用时,动态控制指向,是否打开源码,达到调试sdk源码的目的,而且git分