Android-少不了的 AAR 文件常識,最好知道的注意事項

AAR,爲 Android 而生。

在使用 Eclipse 開發 Android 的那個時代(其實也就幾年前而已),如果想代碼打包,只有 JAR 包一個方法,但是 JAR 只能把 Java 文件代碼打包進去,如果要使用一個有佈局和資源的庫的話,除了將 JAR 放入 libs 外,還需要引入相關的資源和配置文件,十分不優雅。

Android Studio 出來之後,出現了一個新的方法,打包 AAR 文件 ,這個不僅可以把 Java 文件給打進去,還包含 AndroidManifest.xml 和資源文件等,使用的話,直接引入一個 AAR 文件就足夠了,非常方便。

如何 生成 AAR 文件

AAR,名字來源於 Android Archive,見名知義,是一個 Android 庫項目的二進制歸檔文件,使用 Android Studio ,非常簡單可以生成一個 AAR 文件。

1.首先創建一個 Android library Module.

2.等待 Gradle 構建完畢, 就可以在項目名稱/模塊名稱/build/outputs/aar/中找到這個庫項目的 AAR 文件了。

3.如果修改了代碼,也可以通過 Build > Make Project 的方式重新生成文件。

其實這個過程,也生成了對應的 JAR 包,文件在項目名稱/模塊名稱/build/intermediates/bundles/debug(release)/classes.jar,classes.jar 這個library 對應的 JAR 包。

不過在 AAR 文件中,修改後綴名打開後,裏面也有 classes.jar ,和這個 classes.jar 是同樣的內容,

AAR 文件的結構

AAR 文件的文件擴展名爲 .aar,文件本身是一個 zip 文件,以下內容是必須包含的:

  • /AndroidManifest.xml
  • /classes.jar
  • /res/
  • /R.txt

此外,根據打包的 Library Module 情況不同,打包出來的 AAR 文件也可能包含以下內容:

  • /assets/
  • /libs/名稱.jar
  • /jni/abi 名稱/名稱.so(其中 abi 名稱 是 Android 支持的 ABI 之一)
  • /proguard.txt
  • /lint.jar

我們拿到上個步驟中生成的 .aar 文件,手動將後綴名改成 .zip文件,解壓之後的樣子是這個樣子的:

項目中使用 AAR 文件的兩種方式

AAR 文件使用有兩種方式,一種是使用在線的(網上的),一種是添加本地的 AAR 文件。

本地 AAR 使用

1.把 aar 文件放在目標 module 一個文件目錄內,比如就放在 libs 目錄內。

2.在目標 module 的 build.gradle 文件添加如下內容:

repositories {  
    flatDir {  
        dirs 'libs'   
    }  
}

dependencies {  
    compile(name:'AAR的名字', ext:'aar')  
}

遠程 AAR 使用

事實上,在工作項目中,遠程的 AAR 文件的使用頻率比本地高,因爲用起來很方便,我們依賴很多的第三方庫就是遠程一覽的方式。

遠程的 AAR 使用的前提是有一個遠程的庫鏈接,然後通過 Gradle 下載依賴,因此有下面的兩個步驟:

1.rootProject 的 build.gradle 中添加遠程倉庫地址的引用

allprojects {
    repositories {
        // google的官方倉庫
        google()

        // 出名的公共中央倉庫
        jcenter()
        mavenCentral()

        //如果有私庫,也要添加鏈接
        //....
    }
}

其中 google() 是谷爹的官方庫的倉庫地址, jcenter()mavenCentral() 是比較出名的的中央倉庫,基本第三方庫都會上傳到這些倉庫。 有時公司也會有自己的一些封裝庫,不想對外暴露,就放在自己的私有倉庫中,倉庫的地址也要在這裏添加。

2.module 的 build.gradle 中添加具體 aar 的依賴。

dependencies {
    implementation 'com.android.support:support-v4:25.3.1'
}

AAR 使用的注意事項

AAR 使用起來爽歪歪,但是以下問題也要注意,否則使用過程中可能引起不適~

  • 應用模塊的 minSdkVersion 必須大於或等於 Library Module 中定義的版本

    AAR 作爲相關應用模塊的一部分編譯,因此,庫模塊中使用的 API 必須與應用模塊支持的平臺版本兼容,所以 AAR 中的 minSdkVersion 要儘量的設置低一點。

  • 資源合併問題

如果 aar 中有資源文件,集成過程中,很容易出現資源衝突,例如兩個相同名字的圖片什麼的。爲了避免這個問題,有兩種方法,一是制定一個不用衝突的命名規範,二是 library Module 的 build.gradle 中設置資源前綴。第一種,嗯,全靠自覺,維護起來很難,推薦第二種解決方法。


android {
  resourcePrefix "<前綴>"
}

需要說明的是,resourcePrefix 只是起約束作用,不會自動幫你修改資源的名稱,我們需要手動加上前綴,否則報錯!。

  • aar 不能使用 assets 原始資源

    工具不支持在庫模塊中使用原始資源文件(保存在 assets/ 目錄中)。應用使用的任何原始資源都必須存儲在應用模塊自身的 assets/ 目錄中

  • aar 的混淆

    通過對 library Module 的混淆,可以打出一個混淆後的 aar 包,這樣的話,就不用要求在依賴此 aar 的同時,還要手動添加對應的混淆規則了。

    具體做法是:

    1.將混淆規則寫入 lib-proguard-rules.txt。

    2.library Module 的 build.gradle 文件設置 consumerProguardFiles 屬性,引用第一步創建的混淆的文件。

    android {
        defaultConfig {
            consumerProguardFiles 'lib-proguard-rules.txt'
        }
        ...
    }
    

    以上是默認的構建類型,如果 library Module 需要對不同的 buildType 做特別的處理,還需要專門設置。

    1.library Module 的 build.gradle 中設置 publishNonDefault = true,請注意,設置 publishNonDefault 會增加構建時間。

    android {
        ...
        publishNonDefault true
    }
    
    

    2.app 的 build.gradle 中設置不同構建類型的處理。

    
    dependencies {
        debugCompile project(path: ':library', configuration: 'debug')
        releaseCompile project(path: ':library', configuration: 'release')
    }
    

    在依賴本身就帶有混淆規則的 AAR 的時候,AAR 的 ProGuard 文件將附加至 app 的 ProGuard 配置文件 (proguard.txt)。所以,aar 的混淆規則可能會影響 app,因此,制定 aar 的混淆規則的時候,也要謹慎一點,只包括自己的類即可,不要把範圍設置太大。

AAR 內部三方庫依賴的問題

項目的開發過程中,發現一個問題:

使用 Android Studio 打包出來的 AAR ,不會將其依賴的三方庫打包進去。

舉個例子,library Test 依賴了 okhttp,打包成了 Test.aar ,app 使用本地方式引用了 Test.aar,但是無法使用 okhttp,爲了不報錯,app還需要添加 okhttp 依賴。

Google Android Studio 的負責人在 stackoverflow 上解釋了 爲什麼 Android Studio 不能將多個依賴打包進一個 AAR 文件的原因,是因爲將不同的library打包在一起,涉及到資源和配置文件智能合併,所以是個比較複雜的問題,同時也容易造成相同的依賴衝突。

官方雖然不支持,但是開發者的能力是無限的,爲了解決此問題,開發出來了一個 Gradle 插件 android-fat-aar, 這種方式是拋棄 Android Studio 自帶的打包 AAR 的方法,而是自己編寫一個生成 AAR 的腳本。也是很厲害了,但是很不幸,目前來看 gradle 2.2.3+ 以上,這個就不適用了。

不過,不要慌,這個問題可以通過使用 Maven 依賴解決。因爲 library Module 上傳 Maven 後,會生成 一個 .pom 文件,記錄 library Module 的依賴。當 Gradle 依賴 Maven 上的這個庫時,會通過 pom 文件下載對應依賴。如果不想要對應依賴的話,可以通過下面的方法關閉 Gradle 的依賴傳遞。

舉個例子如下:


//正常依賴
implementation 'com.chemao.android:chemao-sdk:1.2.3'

//關閉全部依賴傳遞-方法1
implementation 'com.chemao.android:chemao-sdk:1.2.3@aar'

//關閉全部依賴傳遞-方法2
implementation('com.chemao.android:chemao-sdk:1.2.3') {
        transitive = false
}
    

這樣就皆大歡喜啦!

最後

依賴 Maven 上 Library Module 的前提是 Maven 上有這個庫,於是,下篇博客《 Android-發佈項目到到 JCenter 倉庫》,走起~


歡迎關注個人微信公衆號,最新的博客,好玩的事情,都會在上面分享,期待與你共同成長。
發佈了125 篇原創文章 · 獲贊 367 · 訪問量 124萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章