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分