创建 Android 库

Android 库在结构上与 Android 应用模块相同。它包含构建应用所需的一切,包括源代码、资源文件和 Android 清单。

然而,Android 库不会编译成在设备上运行的 APK,而是编译成 Android 归档 (AAR) 文件,您可以将其用作 Android 应用模块的依赖项。与 JAR 文件不同,AAR 文件为 Android 应用提供了以下功能

  • AAR 文件可以包含 Android 资源和清单文件,这使您可以除了 Kotlin 或 Java 类和方法之外,还可以捆绑共享资源,如布局和可绘制对象。
  • AAR 文件可以包含 C/C++ 库 供应用模块的 C/C++ 代码使用。

库模块在以下情况下很有用

  • 构建多个使用某些相同组件(例如活动、服务或 UI 布局)的应用时
  • 构建存在多个 APK 变体(例如免费版和付费版)且共享核心组件的应用时

在这两种情况下,都将要重用的文件移动到库模块中,然后将该库添加为每个应用模块的依赖项。

此页面介绍如何创建和使用 Android 库模块。有关如何发布库的指南,请参阅 发布您的库

创建库模块

要在项目中创建新的库模块,请按以下步骤操作

  1. 点击文件 > 新建 > 新建模块
  2. 在出现的创建新模块对话框中,点击Android 库,然后点击下一步

    还有一个选项可以创建 Kotlin 或 Java 库,它会构建一个传统的 JAR 文件。虽然 JAR 文件对许多项目(尤其是在您想与其他平台共享代码时)很有用,但它不允许您包含 Android 资源或清单文件,这对于 Android 项目中的代码重用非常有用。本指南重点介绍如何创建 Android 库。

  3. 为您的库命名并为库中的代码选择最低 SDK 版本,然后点击完成

Gradle 项目同步完成后,库模块将显示在项目窗格中。如果看不到新的模块文件夹,请确保窗格显示的是 Android 视图

将应用模块转换为库模块

如果您有一个现有的应用模块,其中包含要重用的代码,则可以将其转换为库模块,方法如下

  1. 打开模块级 build.gradle 文件(如果您使用的是 Groovy),或 build.gradle.kts 文件(如果您使用的是 Kotlin 脚本)。
  2. 删除 applicationId 的行。只有 Android 应用模块才能定义此行。
  3. 找到文件顶部的 `plugins` 块,如下所示

    Groovy

      plugins {
          id 'com.android.application'
      }
      

    Kotlin

      plugins {
          id("com.android.application")
      }
      

    将其更改为以下内容

    Groovy

      plugins {
          id 'com.android.library'
      }
      

    Kotlin

      plugins {
          id("com.android.library")
      }
      
  4. 保存文件并点击文件 > 使用 Gradle 文件同步项目

模块的结构保持不变,但现在它作为 Android 库运行。构建会创建 AAR 文件而不是 APK 文件。

当您想要构建 AAR 文件时,在项目窗口中选择库模块,然后点击构建  > 构建 APK

使用项目结构对话框添加依赖项

您可以使用项目结构对话框向项目添加依赖项。以下部分介绍如何使用该对话框添加依赖项。

在同一项目中使用您的库

要在同一项目中的另一个应用或库模块中使用新 Android 库的代码,请添加项目级依赖项

  1. 导航到文件  > 项目结构  > 依赖项
  2. 选择要添加库的模块。
  3. 声明的依赖项选项卡中,点击 并从菜单中选择模块依赖项

  4. 添加模块依赖项对话框中,选择您的库模块。

    Add module dependency in the Project Structure
Dialog

  5. 选择需要此依赖项的配置,或者如果它适用于所有配置,则选择implementation,然后点击确定

Android Studio 会编辑模块的 build.gradlebuild.gradle.kts 文件以添加依赖项,形式如下

Groovy

  implementation project(path: ":example-library")

Kotlin

  implementation(project(":example-library"))

在其他项目中使用您的库

共享依赖项(JAR 和 AAR)的推荐方法是使用 Maven 存储库,该存储库可以托管在服务(例如 Maven Central)上,也可以使用您本地磁盘上的目录结构。有关使用 Maven 存储库的更多信息,请参阅 远程存储库

当 Android 库发布到 Maven 存储库时,会包含元数据,以便将库的依赖项包含在使用构建中。这允许在库在多个地方使用时自动对其进行重复数据删除。

要在不同项目中的另一个应用模块中使用 Android 库的代码,请按以下步骤操作

  1. 导航到文件  > 项目结构  > 依赖项
  2. 声明的依赖项选项卡中,点击 并从菜单中选择库依赖项

  3. 添加库依赖项对话框中,使用搜索框查找要添加的库。此表单搜索 dependencyResolutionManagement { repositories {...}} 块(位于 settings.gradlesettings.gradle.kts 文件中)中指定的存储库。

    Add library dependency in the Project Structure
Dialog

  4. 选择需要此依赖项的配置,或者如果它适用于所有配置,则选择implementation,然后点击确定

检查应用的 build.gradlebuild.gradle.kts 文件,以确认是否出现了类似于以下内容的声明(具体取决于您选择的构建配置)

Groovy

  implementation 'com.example:examplelibrary:1.0.0'

Kotlin

  implementation("com.example:examplelibrary:1.0.0")

将您的 AAR 或 JAR 添加为依赖项

要在另一个应用模块中使用 Android 库的代码,请按以下步骤操作

  1. 导航到文件  > 项目结构  > 依赖项
  2. 声明的依赖项选项卡中,点击 并从菜单中选择Jar 依赖项

  3. 添加 Jar/Aar 依赖项对话框中,输入 AAR 或 JAR 文件的路径,然后选择依赖项适用的配置。如果库应可用于所有配置,请选择implementation配置。

    Add AAR dependency in the Project Structure
Dialog

    检查应用的 build.gradlebuild.gradle.kts 文件,以确认是否出现了类似于以下内容的声明(具体取决于您选择的构建配置)

    Groovy

      implementation files('my_path/my_lib.aar')
    

    Kotlin

      implementation(files("my_path/my_lib.aar"))
    

要导入在 Android Studio 外部运行的 Gradle 构建上的依赖项,请在应用的 build.gradlebuild.gradle.kts 文件中添加依赖项的路径。例如

Groovy

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar", "*.aar"])
}

Kotlin

dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar", "*.aar"))))
}

有关添加 Gradle 依赖项的更多信息,请参阅 添加构建依赖项

声明公共资源

资源包括项目 res/ 目录中的所有文件,例如图像。库中的所有资源默认都为公共资源。要将所有资源隐式设为私有,您必须将至少一个特定属性定义为公共资源。

要声明公共资源,请将 <public> 声明添加到库的 public.xml 文件中。如果您以前从未添加过公共资源,则需要在库的 res/values/ 目录中创建 public.xml 文件。

以下示例代码创建了两个名为 mylib_app_namemylib_public_string 的公共字符串资源

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

为防止库用户访问仅供内部使用的资源,请通过声明一个或多个公共资源来使用此自动私有指定机制。或者,您可以通过添加一个空的 <public /> 标记来使所有资源都成为私有资源。这表示没有内容是公共的,并且所有资源都是私有的。

任何希望对使用库的开发者保持可见的资源都应设为公共资源。

隐式地将属性设为私有可以防止库用户从内部库资源接收代码完成建议,并允许用户重命名或删除私有资源,而不会破坏库的客户端。私有资源在代码完成中被过滤掉,并且 lint 工具会在您尝试引用私有资源时发出警告。

构建库时,Android Gradle 插件会获取公共资源定义并将它们提取到 public.txt 文件中,然后将其打包到 AAR 文件中。

库模块的开发注意事项

在开发库模块和相关应用时,请注意以下行为和限制。

  • 库按优先级顺序合并。

    将库模块的引用添加到 Android 应用模块后,您可以设置它们的相对优先级。在构建时,库会一个接一个地与应用合并,从最低优先级到最高优先级。

  • 避免资源合并冲突。

    构建工具会将库模块中的资源与相关应用模块的资源合并。如果两个模块中都定义了给定的资源 ID,则将使用应用中的资源。

    如果多个 AAR 库之间发生冲突,则将使用依赖项列表中第一个列出的库(最靠近 dependencies 块顶部)中的资源。

    要避免资源冲突,请使用 非传递性 R。如果这不可行,则考虑使用对模块唯一的(或在所有项目模块中唯一的)前缀或其他一致的命名方案。

  • 在多模块构建中,JAR 依赖项被视为传递依赖项。

    将 JAR 依赖项添加到输出 AAR 的库项目时,库模块会处理 JAR 并将其与 AAR 一起打包。

    但是,如果您的项目包含一个由应用模块使用的库模块,则应用模块会将库的本地 JAR 依赖项视为传递依赖项。在这种情况下,本地 JAR 由使用它的应用模块处理,而不是由库模块处理。这加快了由库代码更改引起的增量构建速度。

    由本地 JAR 依赖项引起的任何 Java 资源冲突都必须在使用库的应用模块中解决。

  • 库模块可以依赖于外部 JAR 库。

    您可以开发一个依赖于外部库的库模块。在这种情况下,相关模块必须针对包含外部库的目标进行构建。

    请注意,库模块和相关应用都必须在其清单文件中声明外部库,方法是在 <uses-library> 元素中声明。

  • 应用模块的 minSdkVersion 必须等于或大于库定义的版本。

    库作为相关应用模块的一部分进行编译,因此库模块中使用的 API 必须与应用模块支持的平台版本兼容。

  • 每个库模块都会创建自己的R类。

    构建依赖的应用模块时,库模块会被编译成一个AAR文件,然后添加到应用模块中。因此,每个库都有自己的R类,其名称根据库的包名命名。

    从主模块和库模块生成的R类会在所有需要的包中创建,包括主模块的包和库的包。

  • 库模块可能包含自己的ProGuard配置文件。

    如果您有一个用于构建和发布AAR的库项目,您可以将ProGuard配置文件添加到库的构建配置中。如果您这样做,Android Gradle插件将应用您指定的ProGuard规则。构建工具将此文件嵌入到库模块生成的AAR文件中。将库添加到应用模块时,库的ProGuard文件将附加到应用模块的ProGuard配置文件(proguard.txt)中。

    通过在库模块中嵌入ProGuard文件,您可以帮助确保依赖于您的库的应用模块不必手动更新其ProGuard文件来使用您的库。当Android Studio构建系统构建您的应用时,它将使用应用模块和库中的指令。因此,无需在单独的步骤中对库运行代码压缩器。

    要将ProGuard规则添加到库项目中,请在库的build.gradlebuild.gradle.kts文件的defaultConfig块内使用consumerProguardFiles属性指定文件名称。

    例如,以下代码片段将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文件还可以包含以下一个或多个可选条目

  • /classes.jar
  • /res/
  • /R.txt
  • /public.txt
  • /assets/
  • /libs/name.jar
  • /jni/abi_name/name.so(其中abi_nameAndroid支持的ABI之一)
  • /proguard.txt
  • /lint.jar
  • /api.jar
  • /prefab/ 用于导出原生库