Android 库的结构与 Android 应用模块的结构相同。它可以提供构建应用所需的一切内容,包括源代码、资源文件和 Android 清单。不过,Android 库将编译为您可以用作 Android 应用模块依赖项的 Android ARchive (AAR) 文件,而不是编译为在设备上运行的 APK。与 JAR 文件不同,AAR 文件会为 Android 应用提供以下功能:
- AAR 文件可以包含多项 Android 资源和一个清单文件,让您除了能够在 Java 类和方法中进行捆绑以外,还能够在布局和可绘制对象等共享资源中进行捆绑。
- AAR 文件可以包含 C/C++ 库,供应用模块的 C/C++ 代码使用。
库模块在以下情况下非常有用:
- 当您要构建多个使用某些相同的组件(例如 Activity、服务或界面布局)的应用时。
- 当您要构建存在于多个 APK 变体中的应用时(例如免费版本和付费版本,并且您需要在这两个版本中使用相同的核心组件)。
无论在哪种情况下,您都只需将想要重复使用的文件移到库模块中,然后将库添加为每个应用模块的依赖项。本页将向您介绍如何执行这两个操作。
创建库模块
要在您的项目中创建新的库模块,请按以下步骤操作:
- 依次点击 File > New > New Module。
- 在随即显示的 Create New Module 窗口中,依次点击 Android Library 和 Next。
还有一个用于创建 Java 库的选项,它可以构建传统的 JAR 文件。虽然 JAR 文件对很多项目(尤其是当您想要与其他平台共享代码时)都很有用,但它不允许您包含 Android 资源或清单文件,而要在 Android 项目中重复使用代码,Android 资源和清单文件是非常有用的。因此,本指南侧重于介绍如何创建 Android 库。
- 为您的库命名,并为库中的代码选择一个最低 SDK 版本,然后点击 Finish。
在 Gradle 项目同步完成后,库模块会显示在左侧的 Project 面板中。如果您没有看到新模块文件夹,请确保显示的是 Android 视图。
将应用模块转换为库模块
如果现有的应用模块包含您想要重复使用的所有代码,您可以按照以下步骤将其转换为库模块:
- 打开模块级
build.gradle
文件。 - 删除
applicationId
行。只有 Android 应用模块才能定义此行。 - 在文件的顶部,您应该看到以下代码:
Groovy
plugins { id 'com.android.application' }
Kotlin
plugins { id("com.android.application") }
将其更改为以下代码:
Groovy
plugins { id 'com.android.library' }
Kotlin
plugins { id("com.android.library") }
- 保存文件,然后依次点击 File > Sync Project with Gradle Files。
大功告成。模块的整个结构仍保持不变,但是现在它会作为 Android 库运行,build 现在也会创建 AAR 文件,而不是 APK。
如果您想要构建 AAR 文件,请在 Project 窗口中选择库模块,然后依次点击 Build > Build APK。
使用“Project Structure”对话框添加依赖项
在同一个项目中使用您的库
如需在同一项目中的另一个应用或库模块中使用新的 Android 库代码,请添加一个项目级依赖项:
- 依次转到 File > Project Structure > Dependencies。
- 选择要在其中使用库的模块。
- 在 Declared Dependencies 标签页中,点击
,然后在下拉菜单中选择 Module Dependency。
在“Add Module Dependency”对话框中,选择您的库模块。
选择需要此依赖项的配置,或选择“implementation”(如果模块适用于所有配置),然后点击“OK”。
Studio 将修改模块的 build.gradle
文件,以添加以下形式的依赖项:
implementation(project(path: ":example-library"))
在其他项目中使用您的库
建议使用 Maven 代码库共享依赖项,Maven 代码库或者托管在 Maven Central 等服务上,或者采用本地磁盘上的目录结构存储。如需详细了解如何使用 Maven 代码库,请参阅远程代码库。
将 Android 库发布到 Maven 代码库时,元数据将会包含在内,这样库的依赖项将包含到正在使用的 build 中,这允许在多个位置使用库时自动删除重复信息。
如需在另一个应用模块中使用您的 Android 库代码,请按以下步骤操作:
- 依次转到 File > Project Structure > Dependencies。
- 在 Declared Dependencies 标签页中,点击
,然后在下拉菜单中选择 Library Dependencies。
在 Add Library Dependencies 对话框中,使用搜索框查找要添加的库。此表单会在
settings.gradle
文件的dependencyResolutionManagement { repositories {...}}
代码块中搜索指定的代码库。选择需要此依赖项的配置,或选择“implementation”(如果库适用于所有配置)。
检查应用的
build.gradle
文件,确认类似于以下内容的声明(具体取决于您选择的构建配置):
implementation 'com.example:examplelibrary:1.0.0'
将 AAR 或 JAR 文件添加为依赖项
如需在另一个应用模块中使用您的 Android 库代码,请按以下步骤操作:
- 依次转到 File > Project Structure > Dependencies。
- 在 Declared Dependencies 标签页中,点击
,然后在下拉菜单中选择 Jar Dependency。
在 Add Jar/Aar Dependency 对话框中,首先输入
.aar
或.jar
文件的路径,然后选择要应用依赖项的配置。 如果库将适用于所有配置,请选择“implementation”配置。检查应用的
build.gradle
文件,确认类似于以下内容的声明(具体取决于您选择的构建配置):implementation files('my_path/my_lib.aar')
或者,如果您要在 Android Studio 之外运行 Gradle build,可以通过在应用的 build.gradle 文件中添加指向某个依赖项的路径来导入该依赖项。例如:
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar", "*.aar"])
...
}
如需详细了解如何添加 Gradle 依赖项,请参阅添加 build 依赖项。
选择要设为公开的资源
库中的所有资源在默认情况下均处于公开状态。如需将所有资源隐式设为私有,您必须至少将一个特定属性定义为公开。资源包括您项目的 res/
目录中的所有文件,例如图像。为了防止库的用户访问仅供内部使用的资源,您应该通过声明一个或多个公开资源的方式来使用这种自动私有标识机制。或者,您也可以通过添加空的 <public />
标记将所有资源设为私有,此标记不会将任何资源设为公开,而是会将一切(所有资源)都设为私有。
如需声明公开资源,请向库的 public.xml
文件添加 <public>
声明。如果您之前未添加过公开资源,则需要在库的 res/values/
目录中创建 public.xml
文件。
以下示例代码会创建两个名称分别为 mylib_app_name
和 mylib_public_string
的公开字符串资源:
<resources> <public name="mylib_app_name" type="string"/> <public name="mylib_public_string" type="string"/> </resources>
如果您希望让任何资源对使用您的库的开发者可见,应该将这些资源设为公开。
通过将属性隐式设为私有,您不仅可以防止库的用户从内部库资源获得代码补全建议,还可以重命名或移除私有资源,而不会破坏库的客户端。系统会从代码补全中过滤掉私有资源,并且 Lint 会在您尝试引用私有资源时发出警告。
在构建库时,Android Gradle 插件会获取公开资源定义,并将其提取到 public.txt
文件中,然后系统会将此文件打包到 AAR 文件中。
库模块开发注意事项
在开发库模块和相关应用时,请注意以下行为和限制。
向 Android 应用模块添加对库模块的引用后,您可以设置它们的相对优先级。在构建时,库会按照优先级由低到高的顺序逐一与应用合并。
资源合并冲突
构建工具会将库模块中的资源与相关应用模块的资源合并。如果这两个模块中都定义了给定的资源 ID,系统会使用应用中的资源。
如果多个 AAR 库之间发生冲突,系统会使用依赖项列表中首先列出的库(靠近
dependencies
块顶部)中的资源。为了避免常用的资源 ID 发生资源冲突,请考虑使用对模块具有唯一性(或在所有项目模块之间具有唯一性)的前缀或其他一致的命名方案。
在多模块构建中,系统会将 JAR 依赖项视为传递依赖项
在向输出 AAR 的库项目添加 JAR 依赖项时,JAR 会由库模块进行处理,并与其 AAR 打包在一起。
不过,如果您的项目包含库模块,并且此模块已被应用模块使用,应用模块便会将库的本地 JAR 依赖项视为传递依赖项。在这种情况下,本地 JAR 将由使用它的应用模块进行处理,而不是由库模块进行处理。这是为了加快库代码更改导致的增量构建的速度。
由本地 JAR 依赖项导致的所有 Java 资源冲突都必须在使用相应库的应用模块中解决。
库模块可以依赖于外部 JAR 库
您可以开发一个依赖于外部库(例如 Google 地图外部库)的库模块。在这种情况下,相关应用必须针对包含此外部库的目标(例如 Google API 插件)进行构建。另外也要注意,库模块和相关应用都必须在其清单文件的
<uses-library>
元素中声明外部库。应用模块的
minSdkVersion
必须等于或大于库定义的版本库是作为相关应用模块的一部分进行编译的,因此,库模块中使用的 API 必须与应用模块支持的平台版本兼容。
每个库模块都会创建自己的 R 类
在您构建相关应用模块时,库模块会先编译到 AAR 文件中,然后再添加到应用模块中。因此,每个库都有自己的
R
类,并根据库的软件包名称命名。所需的所有软件包中都会创建从主模块和库模块生成的R
类,包括主模块的软件包和库的软件包。库模块可以包含自己的 ProGuard 配置文件
如果有用于构建和发布 AAR 的库项目,您可以向库的构建配置添加 ProGuard 配置文件,并且 Android Gradle 插件规则适用于您指定的 ProGuard 规则。构建工具会将此文件嵌入到为库模块生成的 AAR 文件中。在您将库添加到应用模块后,库的 ProGuard 文件会附加到应用模块的 ProGuard 配置文件 (
proguard.txt
)。通过将 ProGuard 文件嵌入到库模块中,您可以确保依赖于相应库的应用模块不必手动更新其 ProGuard 文件即可使用此库。当 Android Studio 构建系统构建您的应用时,它会同时使用来自应用模块和库的指令。因此无需按照单独的步骤在库上运行代码缩减器。
如需向库项目添加 ProGuard 规则,您必须使用
consumerProguardFiles
属性(位于库的build.gradle
文件的defaultConfig
块内)指定文件名称。例如,以下代码段会将lib-proguard-rules.txt
设为库的 ProGuard 配置文件:Groovy
android { defaultConfig { consumerProguardFiles 'lib-proguard-rules.txt' } ... }
Kotlin
android { defaultConfig { consumerProguardFiles("lib-proguard-rules.txt") } ... }
不过,如果库模块是要编译到 APK 中的多模块构建的一部分,并且不会生成 AAR,您应该只在使用相应库的应用模块上运行代码缩减。如需详细了解 ProGuard 规则及其用法,请参阅缩减、混淆处理和优化应用。
-
测试库模块的方法与测试应用的方法相同
主要区别在于,库及其依赖项会作为测试 APK 的依赖项自动包含在内。这意味着测试 APK 不仅包含自己的代码,还包含库的 AAR 及其所有依赖项。由于没有单独的“被测应用”,因此
androidTest
任务只会安装(和卸载)测试 APK。在合并多个清单文件时,Gradle 会遵循默认的优先级顺序,并将库的清单合并到测试 APK 的主清单中。
AAR 文件详解
AAR 文件的文件扩展名为 .aar
,Maven 工件类型应该也是 aar
。此文件本身是一个 zip 文件。唯一的必需条目是 /AndroidManifest.xml
。
此外,AAR 文件可能包含以下一个或多个可选条目: