Android 開發使用 Gradle 配置構建庫模塊的工作方式

Android 開發過程中,我們不可避免地需要引入其他人的工作成果。減少重復“造輪子”的時間,投入到更有意義的核心任務當中。

Android 庫模塊在結構上與 Android 應用模塊相同。提供構建應用所需的一切內容,包括源代碼(src)、資源文件(res)和 Android 清單文件(AndroidManifest.xml)。

Android Studio IDE 提供選項創建庫模塊:

  1. 在項目中創建一個新的庫模塊(New Module
  2. 將應用模塊轉換為庫模塊(因兩者結構基本相同)

如果現有的應用模塊包含希望重用的所有代碼,可以通過修改 build.gradle文件:

// apply plugin: 'com.android.application'
apply plugin: 'com.android.library'
  • Android 庫模塊編譯產物為 AAR,需要作為其他應用模塊依賴項使用。
  • Android 應用模塊編譯產物為 APK,設備上可以直接運行。

Android AAR 類似 Java JAR,除了類文件還可以包含 Android 資源和一個清單配置文件(AndroidManifest.xml)。

導入本地外部模塊

導入本地的外部模塊(e.g. Project B b module)到當前主項目中(e.g. Project A)。
Project B b module 通常為庫模塊,我們需要在另一個 Project A 應用模塊中使用它。

Android Studio IDE 提供選項以依賴項形式來添加庫:

  1. 添加已編譯的 AAR(或 JAR)文件(Import .JAR/.AAR Package
  2. 將庫模塊導入到您的項目中(Import Module

兩者區別如下:

  • 庫模塊導入方式,將會復制代碼到其他項目:
    Project A 目錄下出現 Project B b module 的拷貝
  • 庫模塊導入之后允許編輯庫代碼,但是修改只對當前項目生效:
    Project A 目錄下修改 b module 不會影響到 Project B b module

在現實開發過程中,我們希望維護一個統一版本的庫模塊,這樣一來庫模塊的更新就會同步給所有依賴于它的項目:
Project A、Project C、Project D 都依賴于 Project B b module,庫模塊 b 的修改會同步到各個項目。

  • 庫模塊導入方式顯然無法完成任務,因為其是通過拷貝方式導入。
  • 添加已編譯的 AAR(或 JAR)文件可以完成任務,但是依然需要人工切換項目點選操作。

解決方案:
配置 gradle 通過本地相對路徑指定庫模塊文件夾,實現本地外部模塊導入。

打開主項目 settings.gradle 文件導入庫:

include ':my-library-module'
project(':my-library-module').projectDir = new File(settingsDir, '../my-library-module')

打開主項目應用模塊的 build.gradle 文件,并向 dependencies 塊中添加依賴:

dependencies {compile project(":my-library-module")
}

庫模塊開發注意事項

將庫模塊引用添加至您的 Android 應用模塊后,庫模塊會根據優先級的順序與應用模塊進行合并。

資源合并沖突

  • 當庫模塊與應用模塊均定義了相同資源 ID,默認使用應用模塊的資源,e.g. @string/app_name
  • 多個 AAR 庫之間發生資源 ID 沖突,根據依賴項列表順序,優先使用 dependencies 塊頂部模塊的資源

避免常用資源 ID 沖突的有效辦法,是在各個模塊中使用具有唯一性的前綴命名規范。

AndroidManifest 合并沖突

考慮到兼容性問題,應用模塊的 minSdkVersion 必須大于或等于庫定義的版本。
庫模塊中如若使用到僅高版本 SDK 支持的 API,將會導致應用模塊編譯失敗。
Android 在切換到 Gradle 作為構建系統之前,通過 Manifest 設置 minSdkVersion,之后其值會被 build.gradle 文件中的值覆蓋。

Android 應用的 APK 文件中只能包含一個 AndroidManifest.xml,不過 Android Studio 項目可以包含多個該文件(來自主應用模塊及各個庫模塊)。因此,在構建應用時,Gradle 構建會將所有清單文件(AndroidManifest.xml)合并。清單文件按照優先級從低到高合并,遵循特定規則合并各個清單文件中的所有 XML 元素 。

清單文件優先級由高到低的順序:

  1. 清單文件構建變體
  2. 應用模塊的主清單文件
  3. 所包括庫中的清單文件

多個庫存在時,則其清單優先級與依賴順序即 dependencies 塊中的順序匹配。

Manifest merger failed 示例:
android:theme 在多個 AndroidManifest.xml 被定義且值不同,造成合并沖突。

Project A 主項目 AndroidManifest.xml

<applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/AppTheme">
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

Project B b Library Module AndroidManifest.xml

<applicationandroid:theme="Theme.AppCompat.Light.DarkActionBar">

遇到 Manifest 沖突參考 Gradle Console 給出的錯誤日志和提示,解決沖突。
例如使用 tools:replace 方式避免屬性沖突,借助 tools 域名空間(xmlns:tools="http://schemas.android.com/tools")設置 Manifest 的合并優先級。明確表示合并時移除低優先級 library module 中的相關屬性,使用高優先級 application module 中定義的對應屬性內容。

Project A 主項目 AndroidManifest.xml

<applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/AppTheme"tools:replace="android:theme">

模塊依賴分析

考慮到多重嵌套依賴問題,Gradle 類似 Maven 支持傳遞依賴,即庫本身依賴于其他庫,由此需要解決依賴之間的版本問題。

復雜的依賴關系很可能導致重復引入包,例如:support-v4support-v7 包,從而發生沖突。

多個模塊之間存在相同依賴并且發生沖突,可以通過 exclude 語法過濾相同依賴:

// helloworld build.gradle
...
compile ('com.example.helloworld:my-library-module:1.0.0') {exclude group: 'com.android.support', module: 'support-v4'exclude group: 'com.android.support', module: 'support-v7'
}

上述方法是在主項目引入其他庫模塊時進行過濾依賴,作為庫模塊開發者我們也應該考慮到其他用戶的使用情況。

provided 語法在創建 Android 庫模塊時非常有用,將依賴項添加到編譯過程中,但不會添加到編譯輸出中。這樣一來減少最終 APK、AAR 產物大小,同時避免添加不必要依賴項。

注意:需要告知用戶此依賴項存在,由其如何決定引入依賴。

// my-library-module build.gradle
...
ext.supportLibVersion = '26.1.0'dependencies {implementation fileTree(dir: 'libs', include: ['*.jar'])provided "com.android.support:appcompat-v7:${supportLibVersion}"
}

Project A 依賴 a、b、c module,同時 a、b module 又依賴于 d module,且 a、b 各自依賴的 d module 版本(version)不一致,不同 version 的 d module 中 API 接口如若發生改變,Project A Build/Sync 將會失敗。 例如 version 1.0 中的方法 method1,在 version 2.0 被移除將會遇到 java.lang.NoSuchMethodError

建議盡可能保持依賴項 d module version 一致,或者使用不同 version 但是差異不大,起碼做到 API 能夠通用。

通過 ./gradlew dependencies 命令可以查看依賴關系,附加參數可以查看指定類型、模塊依賴關系:

./gradlew my-library-module:dependencies --configuration archives
archives - Configuration for archive artifacts.
+--- com.android.support:recyclerview-v7:26.1.0
|    +--- com.android.support:support-annotations:26.1.0
|    +--- com.android.support:support-compat:26.1.0
|    |    +--- com.android.support:support-annotations:26.1.0
|    |    \--- android.arch.lifecycle:runtime:1.0.0
|    |         +--- android.arch.lifecycle:common:1.0.0
|    |         \--- android.arch.core:common:1.0.0
|    \--- com.android.support:support-core-ui:26.1.0
|         +--- com.android.support:support-annotations:26.1.0
|         \--- com.android.support:support-compat:26.1.0 (*)

另外 Android 項目可以使用 ./gradlew androidDependencies


另外,考慮到構建問題,庫模塊使用的 gradle 插件與應用模塊盡量保持一致。
Android Gradle Plugin 版本不一致可能會影響到依賴項配置語法:

New configurationDeprecated configuration
implementationcompile
apicompile
compileOnlyprovided
runtimeOnlyapk

引用

創建 Android 庫
Add build dependencies
合并多個清單文件

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/390212.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/390212.shtml
英文地址,請注明出處:http://en.pswp.cn/news/390212.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vue 組件庫發布_如何創建和發布Vue組件庫

vue 組件庫發布Component libraries are all the rage these days. They make it easy to maintain a consistent look and feel across an application. 如今&#xff0c;組件庫風行一時。 它們使在整個應用程序中保持一致的外觀和感覺變得容易。 Ive used a variety of diff…

angular

<input type"file" id"one-input" accept"image/*" file-model"images" οnchange"angular.element(this).scope().img_upload(this.files)"/>轉載于:https://www.cnblogs.com/loweringye/p/8441437.html

Java網絡編程 — Netty入門

認識Netty Netty簡介 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty is a NIO client server framework which enables quick and easy development o…

har文件分析http_如何使用HAR文件分析一段時間內的性能

har文件分析httpWhen I consider the performance of a website, several things come to mind. I think about looking at the requests of a page, understanding what resources are being loaded, and how long these resources take to be available to users.當我考慮網站…

第一階段:前端開發_Mysql——表與表之間的關系

2018-06-26 表與表之間的關系 一、一對多關系&#xff1a; 常見實例&#xff1a;分類和商品&#xff0c;部門和員工一對多建表原則&#xff1a;在從表&#xff08;多方&#xff09;創建一個字段&#xff0c;字段作為外鍵指向主表&#xff08;一方&#xff09;的一方      …

按鈕提交在url后添加字段_在輸入字段上定向單擊“清除”按鈕(X)

按鈕提交在url后添加字段jQuery makes it easy to get your project up and running. Though its fallen out of favor in recent years, its still worth learning the basics, especially if you want quick access to its powerful methods.jQuery使您可以輕松啟動和運行項目…

429. N 叉樹的層序遍歷

429. N 叉樹的層序遍歷 給定一個 N 叉樹&#xff0c;返回其節點值的層序遍歷。&#xff08;即從左到右&#xff0c;逐層遍歷&#xff09;。 樹的序列化輸入是用層序遍歷&#xff0c;每組子節點都由 null 值分隔&#xff08;參見示例&#xff09;。 - 示例 1&#xff1a;輸入…

javascript如何阻止事件冒泡和默認行為

阻止冒泡&#xff1a; 冒泡簡單的舉例來說&#xff0c;兒子知道了一個秘密消息&#xff0c;它告訴了爸爸&#xff0c;爸爸知道了又告訴了爺爺&#xff0c;一級級傳遞從而以引起事件的混亂&#xff0c;而阻止冒泡就是不讓兒子告訴爸爸&#xff0c;爸爸自然不會告訴爺爺。下面的d…

89. Gray Code - LeetCode

為什么80%的碼農都做不了架構師&#xff1f;>>> Question 89. Gray Code Solution 思路&#xff1a; n 0 0 n 1 0 1 n 2 00 01 10 11 n 3 000 001 010 011 100 101 110 111 Java實現&#xff1a; public List<Integer> grayCode(int n) {List&…

400. 第 N 位數字

400. 第 N 位數字 在無限的整數序列 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, …中找到第 n 位數字。 注意&#xff1a;n 是正數且在 32 位整數范圍內&#xff08;n < 231&#xff09;。 示例 1&#xff1a; 輸入&#xff1a;3 輸出&#xff1a;3 示例 2&#xff1a; 輸入&…

1.初識Linux

1.Linux 區分大小寫 2.shell命令行-bash 進入終端->[stulocalhost~]$ (其中,Stu為登錄用戶名&#xff0c;localhost為登錄主機名&#xff0c;’~’ 表示當前用戶正處在stu用戶的家目錄中, 普通用戶的提示符以$結尾&#xff0c;而根用戶以’#’結尾) 3.Linux中所謂的命令(…

這份NLP研究進展匯總請收好,GitHub連續3天最火的都是它

最近&#xff0c;有一份自然語言處理 (NLP) 進展合輯&#xff0c;一發布就受到了同性交友網站用戶的瘋狂標星&#xff0c;已經連續3天高居GitHub熱門榜首位。 合集里面包括&#xff0c;20多種NLP任務前赴后繼的研究成果&#xff0c;以及用到的數據集。 這是來自愛爾蘭的Sebasti…

基于模型的嵌入式開發流程_如何使用基于模型的測試來改善工作流程

基于模型的嵌入式開發流程Unit testing is not enough – so lets start using model-based testing to improve our workflows.單元測試還不夠–因此&#xff0c;讓我們開始使用基于模型的測試來改善我們的工作流程。 Software testing is an important phase in building a …

166. 分數到小數

166. 分數到小數 給定兩個整數&#xff0c;分別表示分數的分子 numerator 和分母 denominator&#xff0c;以 字符串形式返回小數 。 如果小數部分為循環小數&#xff0c;則將循環的部分括在括號內。 如果存在多個答案&#xff0c;只需返回 任意一個 。 對于所有給定的輸入…

最近用.NET實現DHT爬蟲,全.NET實現

最近用.NET實現DHT爬蟲&#xff0c;全.NET實現&#xff0c;大家可以加我QQ交流下 309159808 轉載于:https://www.cnblogs.com/oshoh/p/9236186.html

C++貪吃蛇

動畫鏈接 GitHub鏈接&#xff1a;https://github.com/yanpeng1314/Snake 1 #include "Snake.h"2 3 int iScore 0;4 int iGrade 1;5 6 //蛇頭蛇尾初始位置7 int x_head 1, y_head 3;8 int x_tail 1, y_tail 1;9 10 //地圖坐標11 int i_Map 1, j_Map 1;12 13 /…

遠程辦公招聘_招聘遠程人才時要尋找的5種技能

遠程辦公招聘Remote work is a fast emerging segment of the labor market. How to embrace this shift as an employer - and find, recruit, and empower remote staff - is a question many companies and hiring managers are grappling with.遠程工作是勞動力市場中快速崛…

10分鐘騰訊云配置免費https

騰訊云免費證書申請地址&#xff1a; https://console.cloud.tencent... 填寫相關信息 域名身份驗證 文件驗證 將fileauth.text 創建在網站訪問根目錄的 .well-known/pki-validation/目錄使得 www.**.com/.well-known/pki-validation/fileauth.text 能夠訪問詳情 等待5分鐘左右…

1588. 所有奇數長度子數組的和

1588. 所有奇數長度子數組的和 給你一個正整數數組 arr &#xff0c;請你計算所有可能的奇數長度子數組的和。 子數組 定義為原數組中的一個連續子序列。 請你返回 arr 中 所有奇數長度子數組的和 。 示例 1&#xff1a; 輸入&#xff1a;arr [1,4,2,5,3] 輸出&#xff1…

洛谷P3195 [HNOI2008]玩具裝箱TOY(單調隊列優化DP)

題目描述 P教授要去看奧運&#xff0c;但是他舍不下他的玩具&#xff0c;于是他決定把所有的玩具運到北京。他使用自己的壓縮器進行壓縮&#xff0c;其可以將任意物品變成一堆&#xff0c;再放到一種特殊的一維容器中。P教授有編號為1...N的N件玩具&#xff0c;第i件玩具經過壓…