天天看點

aar 嵌套引用本地 aar 的打包

Android studio 的 module 打包一般會打包成 aar 的形式。如果 module 引用了一個本地的 aar,在打包的時候,這個被引用的 aar 是不會打包進去的,這種設計思想是比較好的,可以很好的避免包沖突的問題。例如 App 引用了兩個 aar(1.aar 和 2.aar),1.aar 和 2.aar 都依賴了第三方的 3.aar,如果1.aar 和 2.aar 都把 3.aar 打包進去的話,App 再引用 1.aar 和 2.aar 的時候就會因為都有 3.aar 發生引用沖突。

實際開發中,會引用第三方的庫,但是,又不想讓引用方知道都是用了什麼第三方的庫,是以就需要把第三方的庫打進到自己的 aar 中,本篇文章就會介紹,這種情況的處理方式。

1、建立工程

看一下項目的目錄結構

aar 嵌套引用本地 aar 的打包

上圖中主要有三個子產品 basiclib、exlib、pkglib

basiclib: 被 exlib 引用的子產品(exlib 會引用 basiclib 打包的 aar),basiclib 内部實作很簡單,隻有一句列印。

aar 嵌套引用本地 aar 的打包

exlib: 需要對外提供的子產品(最終會被打包成 aar 的形式),調用 basiclib 子產品的接口。

aar 嵌套引用本地 aar 的打包

pkglib:負責打包,打包 exlib 所有依賴的包。

2、打包嵌套的 aar

pkglib 主要是負責打包,那就看看 pkglib 的 build.gradle 的實作

apply plugin: 'java'
version = 1.0
buildscript {

    repositories {
        google()
        mavenCentral()
        jcenter()
        maven {
            url "https://maven.google.com"
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.5.3'
    }
}

repositories {
    google()
    mavenCentral()
    jcenter()
    maven {
        url "https://maven.google.com"
    }
}

dependencies {
    implementation project(':exlib') //此處填寫需要打包的Android Library Project name
}

//把所有依賴的 jar 包拷貝至 build/outputs/aar/libs
task syncAllJars() {
    // 使用了絕對路徑,需要根據實際情況調整
    // 将指定路徑下的所有 jar 包,打包至被打包的路徑下
    def dir = new File('D:\\hosh\\android\\hosh\\MqttPhone\\exlib\\libs')
    files(dir.listFiles()).each { file ->
        if (file.name.endsWith('.jar')) {
            copy {
                into buildDir.getPath() + "/outputs/aar/libs"
                from file.absolutePath
            }
        }
    }
}

// 把所有依賴的 aar 包中包含的 classes.jar
// 都拷貝到 build/outputs/aar/libs下,并重命名以不被覆寫
task syncAllAars(dependsOn:':exlib:assemble') {
    def jarName
    def aarPath
    def destDir = buildDir.getPath()+"/outputs/aar"
    // 使用了絕對路徑,需要根據實際情況調整
    def dir = new File('D:\\hosh\\android\\hosh\\MqttPhone\\exlib\\libs')
    files(dir.listFiles()).each { file ->
        aarPath = file.absolutePath

        if (file.name.endsWith('.aar')) {
            jarName = "libs/" + file.name.replace(".aar",".jar")
            copy {
                from zipTree(aarPath)
                into destDir
                include "**/*"
                rename 'classes.jar', jarName
            }
        }
    }
}

// 将多個 jar 包打包成一個 classes.jar
task makeJar(type: Jar) {
    archiveName = 'classes.jar'
    def dir = new File(buildDir.getPath()+"/outputs/aar/libs")
    files(dir.listFiles()).each { file ->

        if (file.name.endsWith('.jar')) {
            from (project.zipTree(file.absolutePath))
        }
    }
    destinationDirectory = file(buildDir.getPath()+"/outputs/aar")
}

task fataar(dependsOn:[syncAllAars, syncAllJars, makeJar]) {
}

//生成最終 aar 包,libs 目錄需要被排除
task genAar(dependsOn:[fataar], type: Zip) {
    def destDir = buildDir.getPath()+"/outputs/aar"
    baseName "wholeSDK"
    extension "aar"
    version '1.1'
    destinationDirectory = file('libs/')
    from destDir
    exclude "libs"
}
           

這裡是有依賴的前提條件的,首先需要将 basiclib 子產品打包,生成 basiclib-debug.aar 複制到 exlib 子產品下的 libs 目錄,同時将 exlib 子產品打包生成 exlib-debug.aar 複制到 exlib 子產品下的 libs 目錄。

aar 嵌套引用本地 aar 的打包

pkglib 的打包過程主要是對 exlib 子產品的 libs 目錄進行處理。

最後執行 gradlew pkglib:genAar 即可

aar 嵌套引用本地 aar 的打包

3、測試嵌套 aar

執行 gradlew pkglib:genAar 指令後,會生成如下的檔案

aar 嵌套引用本地 aar 的打包

其中 build/outputs 目錄下的是中間過程生成的檔案,libs 目錄下是最終需要的 wholeSDK-1.1.aar。

在一個空的項目中,測試一下 wholeSDK-1.1.aar 。

aar 嵌套引用本地 aar 的打包
aar 嵌套引用本地 aar 的打包

看到了 basiclib 中的列印日志,說明打包是成功的。

————————————————

版權聲明:本文為CSDN部落客「右手的滑鼠」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。

原文連結:https://blog.csdn.net/qq_19154605/article/details/105532443