1. 程式人生 > >Android Library的建立及使用詳解

Android Library的建立及使用詳解

Android Library和Android APP、Java Library的區別

Android Library在目錄結構上與Android App相同,它能包含構建APP所需的一切(如原始碼、資原始檔、Android Manifest)。Android App最終被編譯打包成能在Android裝置上執行的APK檔案,但是Android Library被編譯成供其它Android App依賴的Android Archive (AAR)檔案。Java Library最終被編譯打包成Java Archive(JAR)檔案,它不能打包Android資原始檔,但是Android Library不僅能打包Java檔案還能打包Android資原始檔。

Android Library的使用場景

1、 當你需要向其它APP提供一個通用模組時。例如:你需要向其它APP提供通用的賬戶管理模組。
2、 當你需要構建不同的APK,但這些APK有共同核心功能時。例如:你的APP有免費版和付費版,但是它們有相同的核心功能。

在這兩種情況下,只需將要重用的檔案移動到Android Library中,然後將library新增為每個APP模組的依賴項,APP就能直接呼叫library中的功能,而不需要關心library的具體實現。

建立一個Android Library Module

在你的Project中建立一個Android Library Module的步驟如下:
1、 點選File > New > New Module


2、 在Create New Module視窗中點選Android Library,然後點選Next
3、 給library命名(如My Library)並設定minimum SDK version。
Gradle同步完成後你就能在左側的Project面板中看到新建的library了,如圖1所示:
這裡寫圖片描述

把App Module轉換成Android Library Module

如果你的App Module的全部程式碼都可以重用,那麼你可以把這個App Module轉換成Android Library Module,步驟如下:
1、 開啟App Module的build.gradle

檔案。
2、 刪除applicationId這一行。只有App Module才需要定義applicationId
3、 把檔案頂部的

apply plugin: 'com.android.application'

改為

apply plugin: 'com.android.library'

4、 儲存檔案,點選Tools > Android > Sync Project with Gradle Files
這樣就完成了App Module到Android Library Module的轉換。轉換後Module的整個結構不變,但是它已經是一個Android Library Module了,編譯後將生成AAR檔案,而不是APK檔案。在Project面板中選中Library Module,然後點選Build > Build APK,就能編譯生成對應的AAR檔案到build>outputs>aar目錄。

新增依賴Android Library

在其它App Module中使用Android Library中的程式碼的步驟如下:
1、 通過以下任一種方式將Android Library新增到您的Project中(如果您的Android Library就在您的Project中,那麼請跳過此步驟)。
方法一:新增編譯生成的AAR檔案到Project。
a、 點選File > New > New Module
b、 點選Import .JAR/.AAR Package,然後點選Next
c、 輸入AAR檔案的路徑,然後點選Finish
方法二:Import Android Library到Project(library的原始碼就成了Project的一部分)。
a、 點選File > New > Import Module
b、 輸入library的目錄地址,然後點選Finish
這樣library就被copy到Project,且你可以編輯library的程式碼。如果你想只維護一份library的程式碼,那麼應該使用方法一,而不應該使用方法二。
2、 確認已在settings.gradle中配置好library,如:

include ':app', ':mylibrary'

3、 開啟App Module的build.gradle檔案,並在dependencies中做好配置,如:

dependencies {
    compile project(":mylibrary")
}

4、 點選Sync Project with Gradle Files
上述例子中,在App Module用compile添加了名為mylibrary的library作為依賴,如果你只需在特定的產品版本上使用這個library,那麼可以用buildVariantNameCompile替代compile。例如,你只想在”pro”版本上依賴mylibrary,那麼應該做如下配置:

productFlavors {
    pro { ... }
}
dependencies {
    proCompile project(":mylibrary")
}

完成上述步驟後,App Module就能訪問Android Library中的程式碼和資源了,並且編譯時AAR檔案會被打包進APK中。如果你需要獲取AAR檔案,你可以點選Build > Make Project生成它,並在project-name/module-name/build/outputs/aar/中找到它。

釋出library的多產品版本

Android Library按照編譯方式可分為“release”、“debug”版本;按照不同的產品可分為“demo”、“full”版本等。預設情況下,Android Library只向其它Android Project和App Module釋出“release”版本。也就是說,如果一個App Module依賴這個Android Library,即使最終編譯出的APP為“debug”版本,這個Android Library仍釋出“release”版本。然而,你可以在library的build.gradle檔案裡把library配置為預設釋出“debug”版本,如下所示:

android {
  ...
  // 設定library的釋出版本預設為“debug”
  defaultPublishConfig "debug"
}

現在library總是向其它Module釋出“debug”版本,但是如果library需要釋出不同的產品版本,那麼你需要同時給defaultPublishConfig設定編譯方式和產品版本。下面的例子給library設定的產品版本為“demo”,編譯方式為“debug”:

android {
  ...
  defaultPublishConfig "demoDebug"
}

你也可以把library設定為釋出所有版本,那麼每個版本的app就可以使用對應的library版本,如下所示:

android {
  ...
  //告訴Gradle編譯library的所有版本。
  //需要注意的是:因為Gradle需要編譯多個AAR,而不是隻編譯一個AAR,所以這樣會增加編譯時間。
  publishNonDefault true
}

接下來,你需要在app的build.gradle檔案裡配置dependencies,使app使用適合的library版本。例如在app的build.gradle裡配置:當編譯app的“demoDebug”版本時,使用library的“demoDebug”版本;當編譯app的“fullRelease”時,使用library的“fullRelease”版本。如下所示:

android {...}
...

configurations {
  demoDebugCompile {}
  fullReleaseCompile {}
  ...
}

dependencies {
  // 如果library配置了多個版本,那麼你必須在app中配置使用library的哪個版本
  demoDebugCompile project(path: ':mylibrary', configuration: 'demoDebug')
  fullReleaseCompile project(path: ':mylibrary', configuration: 'fullRelease')
  ...
}

把Android library的Resource設定為public

Android Library中的所有Resource(res/目錄中的所有檔案)預設是public屬性。要使所有資源是private屬性,那麼必須至少將一個特定屬性定義為public屬性。為了防止library的使用者訪問library的內部資源,你需要通過申明一個或多個public資源來使library內的其它資源私有化。或者你可以通過新增空的<public /> 標籤使library的所有資源私有化。

如果你想讓某些資源對library的使用者是public的,請先在library的res/values/資料夾下新建一個public.xml檔案,然後在library的public.xml檔案中新增<public>標籤。如把library中名為mylib_app_namemylib_public_string的兩個字串資源申明為public屬性:

<resources>
    <public name="mylib_app_name" type="string"/>
    <public name="mylib_public_string" type="string"/>
</resources>

私有資源不會有程式碼補全建議,且當你非法訪問一個私有資源時theme editor和lint都會有相應警告。資源私有化不僅防止library的使用者遇到來自library資源的程式碼補全建議,而且允許你對library的資源進行重新命名或刪除,而不用考慮對library使用者的相容性。編譯Android Library時,Android Gradle plugin會蒐集所有public資源並匯入到public.txt檔案中,最終打包進AAR檔案。

Android Library開發注意事項

App Module新增依賴Android Library時可以設定library的優先順序,在編譯時,app按照library從低到高的優先順序依次與每個library合併。開發Android Library和相關APP時,請注意下面事項:
•資源合併衝突
編譯工具會合並library和app的資源。如果某個resource ID在兩個Module中都定義了,那麼會使用app的資源。
如果衝突發生在多個AAR之間,那麼會優先使用dependencies列表中排在前面的library的資源。
為了防止Module直接資源衝突,請給每個Module的資源使用唯一的字首或名稱空間,就像用包名唯一確認一個APP一樣。

•Android Library可以包含JAR Library
可以在Android Library中使用JAR Library,並且依賴這個Android Library的App Module也需要配置好對這個JAR Library的引用。

•Android Library可以依賴external JAR library
Android Library可以依賴external JAR library,如一個地圖的external library,那麼依賴這個Android Library的App Module編譯時必須要依賴包含這個external library的target,如Google APIs Add-On。Android Library Module和App Module都必須要在Manifest檔案中用<uses-library>申明使用這個external library。

•App Module的minSdkVersion必須等於或大於Android Library的minSdkVersion。
Android Library是作為App Module的一部分被編譯的,所以它使用的API必須要與App Module支援的平臺版本相匹配。

•每個Android Library獨自建立其R class
當編譯App Module時,Android Library被編譯成AAR檔案然後被新增到App Module。所以每個Android Library有其獨有的R class,並根據其包名命名。App Module和Android Library的R class被生成長它們各自的package下。

•Android Library可以有獨自的ProGuard配置檔案
每個Android Library可以有自己的ProGuard配置檔案,編譯工具會把這個檔案嵌入到生成的AAR檔案中。當Android Library新增到App Module時,library的ProGuard檔案會附加到App Module的ProGuard檔案。當App Module執行ProGuard檔案時,它會執行App和library的ProGuard檔案,所以你不需要單獨執行library的ProGuard檔案。

在library的build.gradle中用consumerProguardFiles配置library的ProGuard檔案,如下所示把lib-proguard-rules.txt配置為library的ProGuard檔案:

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

•測試Android Library與測試App一樣
主要的不同是Android Library和它依賴的dependencies自動被包含成Test APK的依賴項。即Test APK不僅包含其自身的程式碼,還包含Android Library的AAR和相關依賴。因為沒有單獨的”app under test”,所以androidTest任務只安裝/解除安裝Test APK。

當合並多個Manifest檔案時,Gradle按照預設的優先順序順序把library的manifest合併到APP的manifest。

AAR檔案的結構

AAR檔案的字尾名是.aar,且在Maven中的型別也是aar。AAR檔案本身是一個zip檔案,包括下面內容:
/AndroidManifest.xml
/classes.jar
/res/
/R.txt
/public.txt
通常AAR檔案可能包含下面的一個或多個可選檔案
/assets/
/libs/name.jar
/jni/abi_name/name.so ( abi_name 是Android 支援的一種ABI)
/proguard.txt
/lint.jar