创建 Android 库

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

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

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

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

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

在任一情况下,将您想要重用的文件移至库模块,然后将该库添加为每个应用模块的依赖项。

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

创建库模块

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

  1. 点击 File > New > New Module(文件 > 新建 > 新建模块)。
  2. 在出现的Create New Module(创建新模块)对话框中,点击 Android Library(Android 库),然后点击 Next(下一步)。

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

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

Gradle 项目同步完成后,库模块会显示在 Project(项目)窗格中。如果您没有看到新的模块文件夹,请确保窗格正在显示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. 保存文件并点击 File > Sync Project with Gradle Files(文件 > 使用 Gradle 文件同步项目)。

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

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

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

您可以使用 Project Structure(项目结构)对话框向项目添加依赖项。以下各节介绍如何使用该对话框添加依赖项。

在同一项目中使用您的库

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

  1. 导航到 File > Project Structure > Dependencies(文件 > 项目结构 > 依赖项)。
  2. 选择您要添加库的模块。
  3. Declared Dependencies(声明的依赖项)标签页中,点击 并从菜单中选择 Module Dependency(模块依赖项)。

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

    Add module dependency in the Project Structure
Dialog

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

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. 导航到 File > Project Structure > Dependencies(文件 > 项目结构 > 依赖项)。
  2. Declared Dependencies(声明的依赖项)标签页中,点击 并从菜单中选择 Library Dependency(库依赖项)。

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

    Add library dependency in the Project Structure
Dialog

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

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

Groovy

  implementation 'com.example:examplelibrary:1.0.0'

Kotlin

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

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

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

  1. 导航到 File > Project Structure > Dependencies(文件 > 项目结构 > 依赖项)。
  2. Declared Dependencies(声明的依赖项)标签页中,点击 并从菜单中选择 Jar Dependency(Jar 依赖项)。

  3. Add Jar/Aar Dependency(添加 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.xml 文件中添加一个 <public> 声明。如果您之前未添加公共资源,则需要在库的 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 应用模块后,您可以设置它们的相对优先级。在构建时,库会与应用逐一合并,从最低优先级到最高优先级。

    库中的资源引用将引用合并后的资源,而不一定是库资源。当存在同名资源时,库模块无法强制使用其自身的资源而不是应用或其他库的资源。

  • 避免资源合并冲突。

    构建工具会将库模块中的资源与依赖应用模块中的资源合并。如果给定资源名称在两个模块中都定义,则使用来自应用的资源。

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

    为避免资源冲突,请考虑使用前缀或其他与模块唯一(或在所有项目模块中唯一)的一致命名方案。

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

    当您向输出 AAR 的库项目添加 JAR 依赖项时,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/ 用于导出原生库