1. 程式人生 > >Android和Maven倉庫那些事

Android和Maven倉庫那些事

背景

當一個專案的業務線越來越多的時候,人員也會越來越多,多條業務線同時進行開發,專案也會越來越大,如果不進行統一的管理,勢必會很亂,而且非本條業務線的人員不需要關心其他業務的程式碼,也不需要把所有程式碼都克隆到本地才能進行構建,不然的話就太麻煩了,而且當業務有交叉的時候,可能會隨意修改別的業務的程式碼(當然這可以通過git的許可權來解決,但始終是不好的方式)。這個時候就可以把非本條業務線的所有的模組全都做成JAR包或者AAR包,然後通過maven私服的方式,用gradle來進行構建,自動引入到本地來進行依賴和引用,當然自己的業務線也要這樣做,來提供給別人去引用,如此一來,豈不美哉!

maven簡介

maven是什麼

Maven是一個專案管理和綜合工具,基於專案物件模型(POM)的概念,可以通過一小段描述資訊來管理專案的構建,報告和文件的軟體專案管理工具。當然這是官方的解釋,用我們自己的話來說,maven就是用來構建和管理專案的,就是一個專案的倉庫,我們平時使用到的都是最基本的功能,比如自己開發了一個開源工具,秉著開源的精神,想要讓全世界的人都可以去用,這個時候我們就可以上傳到maven中心庫,這個庫是網路上的一個倉庫,任何人都可以引用裡面的資源,包含了非常多的開源專案。再比如我們公司內部寫了一些通用元件或者工具,但是又只能內部使用,我們就可以搭建公司內部的maven伺服器,把這些專案上傳上去,這樣整個公司所有專案都可以輕鬆的去引用,避免的重複編寫拷貝造成的混亂和麻煩。

POM是什麼

POM就是“Project Object Model”。翻譯過來就是專案物件模型,裡面存放的都是專案的一些基本描述資訊,它是一個xml檔案。maven也就是根據這個配置檔案來進行專案的管理和構建的。先來看看裡面到底是啥:

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion> <groupId>com.tb.plugin</groupId> <artifactId>package-apk</artifactId> <version>1.0.0</version> <!-- 專案產生的構件型別,例如jar、war、aar、pom。外掛可以建立他們自己的構件型別,所以前面列的不是全部構件型別 --> <packaging> jar </packaging> </project>

要注意的是,每個專案只有一個POM檔案。

  • 所有的 POM 檔案要專案元素必須有三個必填欄位: groupId,artifactId,version
  • 在庫中的專案符號是:groupId:artifactId:version
  • pom.xml 的根元素是 project,它有三個主要的子節點。
節點 描述
groupId 這是專案組的編號,這在組織或專案中通常是獨一無二的。 例如,一家銀行集團com.company.bank擁有所有銀行相關專案。
artifactId 這是專案的ID。這通常是專案的名稱。 例如,consumer-banking。 除了groupId之外,artifactId還定義了artifact在儲存庫中的位置。
version 這個就是專案的版本號,每次有新功能或者bug修復,可以修改版本號再去釋出。

maven倉庫分類

  • Maven本地資源庫
    Maven 的本地資源庫是用來儲存專案的依賴庫,預設的資料夾是 “.m2” 目錄,可能需要將其更改為另一個資料夾。
  • Maven中央儲存庫
    Maven 中央儲存庫是 Maven 用來下載所有專案的依賴庫的預設位置。
  • 如何從Maven遠端儲存庫下載?,如何新增遠端庫?
    並非所有的庫儲存在Maven的中央儲存庫,很多時候需要新增一些遠端倉庫來從其他位置,而不是預設的中央儲存庫下載庫。比如Android中用的倉庫就是谷歌基於mavenCentral進行擴充套件的JCenter倉庫,還有google倉庫。

本文主要講解本地maven倉庫的搭建和在專案中的引用。

用maven搭建私服

好了,上面說了這麼多廢話,終於要進入今天的正題了,下面就帶你一步一步搭建自己的maven私服,本文以Nexus Repository Manager為例,版本選擇2.xx,下載地址:https://www.sonatype.com/download-oss-sonatype,由於我的電腦是windows,所以選擇zip檔案即可。下載完成後解壓,找到如下目錄:D:\nexus-2.14.9-01-bundle\nexus-2.14.9-01\bin\jsw,可以看到裡面有很多平臺可以選擇,這裡我選擇的是
windows-x86-64,然後點選install-nexus.bat,進行服務的安裝,成功之後,點選start-nexus.bat啟動服務,然後在瀏覽器輸入http://localhost:8081/nexus即可訪問。我們點選右上角的Log In,輸入預設的使用者名稱密碼:admin,admin123,到此maven私服就算是搭建好了,是不是非常簡單啊~
這裡寫圖片描述

左邊目錄側欄裡面我們點選Repositories可以看到有一些預設倉庫:
這裡寫圖片描述

其中就包含了預設的Releases和Snapshots,這也是我們上傳專案和引用所需要的地方,當然這個是預設的,我們也可以新增自己的,點選圖中的Add按鈕,選擇group就可以新增一個組了,預設的組是public,圖中我添加了tb的組:
這裡寫圖片描述

我們把Releases和Snapshots新增到這個組裡即可,方便我們後續使用。我們點選上面的Releases:
這裡寫圖片描述

可以看到這是它的一些配置,release我們預設不允許重複deploy,所以選擇的Disable Redeploy,其他選項看字面意思也很容易理解,而snapshot這一項就是Allow Redeploy,其他都是一樣的,這裡不做深入介紹了。

上傳Android專案到maven庫

那麼怎麼去上傳我們的專案到這個maven私服呢,直接上程式碼(以我們上一篇中的gradle外掛專案為例,傳送門):

apply plugin: 'groovy'
apply plugin: 'maven'

dependencies {
    compile gradleApi()
    compile localGroovy()
}

uploadArchives {
    repositories {
        mavenDeployer {
            pom.groupId = 'com.tb.plugin'
            pom.artifactId = 'package-apk'
            //最後必須是-SNAPSHOT
            pom.version = IS_PUBLISH.toBoolean() ? VERSION : VERSION + '-SNAPSHOT'

            //傳到本地目錄
            //repository(url: uri('../tplugins'))
            //傳到本地maven私服
            repository(url: IS_PUBLISH.toBoolean() ? 'http://localhost:8081/nexus/content/repositories/releases/' : 'http://localhost:8081/nexus/content/repositories/snapshots/') {
                authentication(userName: 'admin', password: 'admin123')
            }
        }
    }
}

上一篇文章中我們把外掛傳到了本地的maven倉庫,這裡相比,改動的僅僅是maven地址,由本地改為私服地址,這個地址可以在上圖中找到,就是倉庫後面的那一串地址。另外為了方便配置,我們這裡在gradle.properties檔案中加入了兩個變數來控制上傳:

IS_PUBLISH = false
VERSION = 1.0.0

一般情況下,我們在開發階段由於要頻繁修改程式碼,所以要用snapshot版本的包,也就是開發包,而最終上線的時候才去上傳release的包,這樣就不需要頻繁改動版本號了,其他引用人員也無需任何變動,只要我們改動後upload一下,別人就能引用我們的最新包了,這裡需要在工程的gradle檔案中配置一下快取策略來保證每次都是從maven倉庫拉取最新的snapshot包,而不是上一次快取的:

allprojects {
    repositories {
        google()
        jcenter()
    }
    configurations.all {
        resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
    }
}

這樣所有的模組都不需做任何改動,就能實時拉取最新的包,非常方便。

注意:snapshot版本的版本號後面必須加上-SNAPSHOT(中劃線,全大寫),否則引用的時候會找不到包。
我們來看一下最終上傳上去的是什麼樣:

這裡寫圖片描述

可以看到每次上傳的snapshot都在這裡儲存著,並且按照時間進行排列,maven會自動引用最新的包對於同一個版本號,是不是非常牛逼~

引用maven庫

做了這麼多工作,終於可以引用我們的jar/aar包了,看程式碼:

buildscript {
    apply from: "version.gradle"

    repositories {
        google()
        jcenter()
//        maven{
//            url './tplugins'
//        }
//        maven{
//            url 'http://localhost:8081/nexus/content/repositories/releases/'
//        }
//        maven{
//            url 'http://localhost:8081/nexus/content/repositories/snapshots/'
//        }
//        maven{
//            //預設的public組,包含全部預設的倉庫
//            url 'http://localhost:8081/nexus/content/groups/public'
//        }
        maven{
            //自己建立的組,包含release和snapshot
            url 'http://localhost:8081/nexus/content/groups/tb'
        }
    }
    dependencies {
        classpath "com.android.tools.build:gradle:$androidGradleVersion"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"


        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
        classpath 'com.tb.plugin:package-apk:1.0.0-SNAPSHOT'
    }
}

apply plugin: 'com.tb.plugin.package-apk'

可以看到,我們寫了release和snapshot兩個地址,這是非常不方便的,所以有了一開始組的概念,這樣我們最終只需要引入一個組的地址即可,裡面包含了該組所有的倉庫,classpath裡面引入snapshot必須加入-SNAPSHOT,最後一行引入我們的外掛,編譯一下,完美通過。

最後

整個Android中上傳和引用maven私有庫到此就講完了,是不是非常簡單~
有疑問的同學可以在下方留言,最後放出原始碼下載