1. 程式人生 > >多模組依賴打包aar/jar的方法以及遇到的坑

多模組依賴打包aar/jar的方法以及遇到的坑

內容介紹

  1. 多模組依賴打包成aar方法介紹
  2. 多模組依賴打包成jar的方法介紹
  3. 使用過程中踩到的一些坑
  4. 總結

1. 多模組依賴打包成aar方法介紹

在你工程裡某個模組新增的外掛為library的時候,編譯生成的產物就是aar包(其實就是個壓縮包裡面裝了資原始檔跟jar還有些配置檔案,直接解壓就能看到)。
在studio編aar的時候,只會將你的當前模組的內容打包,儘管你依賴了其他模組,也不會將其他模組的東西打進去(遠端依賴除外,因為遠端依賴指向是一個遠端地址,只要指向對了,就能在使用aar的時候被找到)。

接著使用embedded 依賴其他模組
embedded project(’:modelA’)
這樣打包的時候,就會幫你把embedded的模組的內容打包進去了。

這種巢狀依賴引發的問題
相容性問題。目前fat-aar最新版本只支援到gradle 2.3.3版本。因為更高的gradle版本build的產物目錄有所變更。fat-aar實現邏輯其實就是幫你把其他模組生成制build目錄下*.class以及資源拷貝到需要打包的模組,然後再進行打包。所以要是產物目錄變了,就會出問

2.多模組依賴打包成jar的方法介紹

jar包打包起來比aar簡單得多,因為不需要到資原始檔。只需要將所有class檔案打包在一起就行了。而且gradle也提供有打jar的task type。所以這裡使用自定義task來做。不過需要注意的是,打包需要排除部分檔案,不如R檔案、BuildConfig檔案。

栗子:
modelB依賴了modelA,現在需要將模組modelB打包成一個jar,並且產生jar的路徑為modelB檔案目錄下的output資料夾。

//執行順序
//build -> deleteOldTmpDirAndJar-> copyClasses -> makeJavadoc(生成javadoc) -> makeJavadocToJar(打包javadoc) -> assembleJar

//該task作用是刪除久的jar包以及久的臨時檔案
task deleteOldTmpDirAndJar(type: Delete, dependsOn: build) {
    println("=============== Delete old ./output ===============")
    delete './output'
    println("=============== Delete old tmpJarDir ===============")
    delete './build/tmpJarDir'
    println("=============== Delete old tmpJavaDoc ===============")
    delete './build/tmpJavaDoc'
}

//拷貝class檔案
task copyClasses(type: Copy, dependsOn: deleteOldTmpDirAndJar) {
    println("=============== copyClasses ===============")
    from('../modelA/build/intermediates/classes/release')
    from('build/intermediates/classes/release')
    into('./build/tmpJarDir')
    exclude('**/R.class')
    exclude('**/BuildConfig.class')
}

//產生javadoc,有需要的同學可以保留
task makeJavadoc(type: Javadoc, dependsOn: copyClasses) {
    println("===============make Javadoc ===============")
    options.encoding = "UTF-8"
    options.charSet = 'UTF-8'
    options.setMemberLevel(JavadocMemberLevel.PUBLIC)
    source = android.sourceSets.main.java.srcDirs
    classpath += project.files('build/tmpJarDir/')
    destinationDir = reporting.file("../tmpJavaDoc/")
    exclude '**/BuildConfig.java'
    exclude '**/R.java'
    failOnError false
}

//將javadoc檔案目錄打成壓縮包,有需要的同學可以保留
task makeJavadocToJar(type: Jar, dependsOn: makeJavadoc){
    println("=============== Javadoc To Jar ===============")
    archiveName = 'modelBJavaDoc.jar'
    from('./build/tmpJavaDoc')
    destinationDir = file('./output')
}

//將class檔案打成jar包
task assembleJar(type: Jar, dependsOn: makeJavadocToJar){
    println("=============== assembleJar ===============")
    archiveName = 'modelB.jar'
    from('./build/tmpJarDir')
    destinationDir = file('./output')
    exclude('com/xxx/modelA/BuildConfig.class')
    exclude('com/xxx/modelB/BuildConfig.class')
}

3. 使用過程中踩到的一些坑

① 使用embedded的坑

如果你使用了modelB使用了embedded方式依賴了medelA。而modelC又依賴了modelB的時候。你會發現,你怎麼編譯modelC都會報錯

Multiple dex files define Lcom/xxx/xxx/xxx

原因是在modelB build了之後fat-aar外掛會幫你把modelA的build目錄的class檔案拷貝到了modelB 的build檔案目錄裡面去。因為你依賴了modelA的關係,studio在編譯過程中也會去modelA的build檔案目錄去找class檔案。所以導致了modelA的build目錄的class跟modelB裡面的重複了。
“實際上,fat-aar的embedded其實是compile的一個封裝”
在這裡插入圖片描述

那上面說的這個問題怎麼解決呢,我這裡提供一個方法供參考 。要是大家有什麼更好的方法,也可以分享下。
我這邊的需求是上傳maven倉庫的時候才用到embedded的依賴,其他情況都使用compile。所以我通過gradle執行的task來區分依賴的型別

def dependType = 'compile'
gradle.startParameter.taskNames.each({
    String taskName = it
    if(taskName.contains("uploadArchives")) { //當task是上傳maven的時候使用巢狀依賴
        dependType = 'embedded'
        return
    }else{
        dependType = 'compile'
    }
})


dependencies {
    if (dependType.equals("embedded")){
        embedded project(':modelA')
    } else{
        compile project(':modelA')
    }
}

後續在使用中遇到什麼坑,再補充。未完待續!

總結

使用embedded的依賴進行多模組打包aar的方式,是目前比較多人採用的一種方式。多模組打包aar並不是完全沒有其他的方式,比方說使用遠端依賴的方式也是可以的,不過比較麻煩。
如果大家覺得我哪裡不對或者有疑問的地方,可以在評論區留意,一起交流學習。

相關推薦

模組依賴打包aar/jar方法以及遇到的

內容介紹 多模組依賴打包成aar方法介紹 多模組依賴打包成jar的方法介紹 使用過程中踩到的一些坑 總結 1. 多模組依賴打包成aar方法介紹 在你工程裡某個模組新增的外掛為library的時候,編譯生成的產物就是aar包(其實就是個壓縮包裡面裝了資原始檔跟

SpringCloud模組依賴打包問題

Maven:多模組打包報錯 Failed to read artifact descriptor for xxx:jar 1)專案中有多個模組,例如:父模組1,子模組2,common模組。現在需要在子模組2中引用common模組中的內容。在已經成功將common模組的jar安裝到本地倉庫後, 編譯子模組2

Spring-boot構建模組依賴工程時,maven打包異常:程式包xxx不存在

在qizhi專案改版的時候, 所有程式碼都遷移好了, 但是compile的時候報程式包*****不存在, 具體到某一個類就是: 找不到符號. 下面這篇文章是正解 http://hbxflihua.iteye.com/blog/2431537 具體內容如下: =======================

maven模組專案打包war包或者jar

序言: 打包jar包: jar包時springboot推薦的打包方式,這種型別的檔案直接java -jar 檔名 就可以直接執行。 新增maven外掛: 首先第一步在專案的pom.xml檔案中新增 maven外掛: <build>

eclipse如何把java程式碼,打包jar檔案以及轉換為exe可執行檔案

1、背景:     學習java時,教材中關於如題問題,只有一小節說明,而且要自己寫麻煩的配置檔案,最終結果卻只能轉換為jar檔案。實在是心有不爽。此篇部落格教你如何方便快捷地把java程式碼,打包成jar檔案以及轉換為exe可執行檔案 2、前言:     我們都知道

eclipse -- 手把手教你如何把java程式碼,打包jar檔案以及轉換為exe可執行檔案

1、背景:     學習java時,教材中關於如題問題,只有一小節說明,而且要自己寫麻煩的配置檔案,最終結果卻只能轉換為jar檔案。實在是心有不爽。此篇部落格教你如何方便快捷地把java程式碼,打包成jar檔案以及轉換為exe可執行檔案 2、前言:     我們都知道Java可以將二進位制程式打包成可執

android模組依賴傳遞

這幾天在搞多模組化,使用android studio 3.1.3時候出現一個問題: app 依賴 module A(型別android library),module A又依賴module B(型別android library),在module B中建立工具類想在app中呼叫;結果發現

eclipse maven模組專案打包

首先:default VM arguments  新增:-Dmaven.multiModuleProjectDirectory=$M2_HOME maven install 1、執行父工程 2、執行配置檔案 3、執行工具包 4、執行子工程(如果裡面依賴了其子模組,先執行子模

關於maven專案模組打包問題的血淚經歷(必看)

最近公司使用springboot開發專案,使用的構建工具是maven,專案分了很多模組,並且模組之間還存在一定的依賴,比如說一個專案common是提供各專案通用的工具類,公共的類等 例子:專案root,有module common,front,mall等其中front 和mall都依賴於c

Netty入門之建立Maven模組依賴專案

新學Netty,編譯執行時踩了一些坑,記錄在此。 essential netty in action中有一個入門demo,EchoServer and EchoClient,用於Netty入門的小demo。 (Essential Netty in Action)EchoCli

Maven POM 檔案中的中的繼承(Inheritance)和 聚合(Aggregation)- IDEA 和 Eclipse 中模組專案的 Maven 組織方法

Maven POM 檔案中的繼承和聚合(Inheritance & Aggregation) 之前在 IDEA 裡建了一個專案專門用來學習,每個知識點都建立一個相應的模組,方便學習和檢視。今天在建第二個模組的時候發現,這個模組很多的 Mave

spring模組依賴時,被依賴模組的配置檔案不生效的問題解決

maven專案中,現有一個web模組,對外提供http服務的,還有一個內部log模組是專門記錄日誌的,其中兩個模組,都有一個application.yml配置檔案,在配置的過程中,我遇到的問題是,web模組dependency log模組時,log模組的配

maven模組工程打包部署

     一般maven多模組工程結構如下圖,圖中分為dao資料層和上層web層(當然還可以有service層),在進行多模組劃分的時候,一般將dao層採用jar進行打包,web層進行war打包。在進

maven 模組合併打包

使用 maven-shade-plugin 外掛實現多模組專案開發,合併 class 打包成一個jar 包 <plugin> <groupId>org.apa

idea springcloud- maven 模組打包:

父類pom.xml 新增如下: <build> <plugins> <!--編譯外掛--> <plugin> <groupId>org.apache.

Maven模組專案打包前的一些注意事項(打包失敗)

一、 最近在打包Maven專案時遇到了點問題,這個專案是Maven多模組專案,結構如下: projectParent├── xxxx-basic├── xxxx-web1├── xxxx-collector└── xxxx-web2 projectParent 為父專案,無任何程式碼

SpringBoot+Maven模組專案(建立、依賴打包可執行jar包部署測試)完整流程

開發環境:IDEA,                   SprngBoot 2.0.4,                   Maven 2.19.1 工程結構:                              父工程father            

SpringBoot Maven模組整合MyBatis 打包jar

最近公司開始新的專案,框架選定為SpringBoot+Mybatis,本篇主要記錄了在IDEA中搭建SpringBoot多模組專案的過程。 原始碼:https://github.com/12641561/summer summer-api summer-common summer-

【spring cloud】【IDEA】【Maven】spring cloud模組打包打包jar包只有幾k,jar包無法執行,執行報錯:no main manifest attribute, in /ms-eureka.jar

======================================================================================== 引申:maven打包多模組spring cloud服務報錯 程式包XXX不存在 : https://www.cnblog

SpringBoot建立模組方式以及打包方式

       springboot重構多模組的步驟   模型層:model   持久層:persistence   表示層:web   步驟:   正常建立一個springboot專案   修改建立專案的pom檔案,將jar修改為pom   選擇根專案,New–Modul