创建 Android 库

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

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

  • AAR 文件可以包含多项 Android 资源和一个清单文件,让您除了能够在 Kotlin 或 Java 类和方法中进行捆绑以外,还能够在布局和可绘制对象等共享资源中进行捆绑。
  • AAR 文件可以包含 C/C++ 库,供应用模块的 C/C++ 代码使用。

库模块在以下情况下非常有用:

  • 构建使用某些相同组件(例如 activity、服务或 UI 布局)的多个应用
  • 构建存在于多个 APK 变体中的应用,例如使用相同核心组件的免费版本和付费版本

无论在哪种情况下,您都只需将想要重复使用的文件移到库模块中,然后将库添加为每个应用模块的依赖项。

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

创建库模块

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

  1. 依次点击 File > New > New Module
  2. 在随即显示的 Create New Module 对话框中,依次点击 Android LibraryNext

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

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

在 Gradle 项目同步完毕后,库模块会显示在左侧的 Project 窗格中。如果您没看到新模块文件夹,请确保窗格当前显示的是 Android 视图

将应用模块转换为库模块

如果现有的应用模块包含您想重复使用的代码,您可以按照以下步骤将其转换为库模块:

  1. 如果您使用的是 Groovy,请打开模块级 build.gradle 文件;如果您使用的是 Kotlin 脚本,请打开 build.gradle.kts 文件。
  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

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

如果您想构建 AAR 文件,请在 Project 窗口中选择库模块,然后依次点击 Build > Build APK

使用“Project Structure”对话框添加依赖项

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

在同一个项目中使用您的库

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

  1. 依次选择 File > Project Structure > Dependencies
  2. 选择要添加库的模块。
  3. Declared Dependencies 标签页中,点击 ,然后从菜单中选择 Module Dependencies

  4. Add Module Dependency 对话框中,选择您的库模块。

    在“Project Structure”对话框中添加模块依赖项

  5. 选择那个需要此依赖项的配置,或选择 implementation(如果库适用于所有配置),然后点击 OK

Android Studio 会修改模块的 build.gradlebuild.gradle.kts 文件,以便按以下方式添加依赖项:

Groovy

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

Kotlin

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

在其他项目中使用您的库

建议使用 Maven 制品库共享依赖项(JAR 和 AAR),Maven 制品库或者托管在 Maven Central 等服务上,或者以目录结构的形式存储在本地磁盘上。如需详细了解如何使用 Maven 制品库,请参阅远程仓库

将 Android 库发布到 Maven 制品库时,元数据将会包含在内,以使库的依赖项包含在正在使用的 build 中。这样一来,如果在多个位置使用了该库,它就可以自动删除重复信息。

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

  1. 依次选择 File > Project Structure > Dependencies
  2. Declared Dependencies 标签页中,点击 ,然后在菜单中选择 Library Dependencies

  3. Add Library Dependencies 对话框中,使用搜索框查找要添加的库。此表单会在 settings.gradlesettings.gradle.kts 文件的 dependencyResolutionManagement { repositories {...}} 代码块中搜索指定的代码库。

    在“Project Structure”对话框中添加库依赖项

  4. 选择那个需要此依赖项的配置,或选择 implementation(如果库适用于所有配置),然后点击 OK

检查应用的 build.gradlebuild.gradle.kts 文件,确认是否显示了与下方示例类似的声明(具体取决于您选择的 build 配置):

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

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

    在“Project Structure”对话框中添加 AAR 依赖项

    检查应用的 build.gradlebuild.gradle.kts 文件,确认是否显示了与下方示例类似的声明(具体取决于您选择的 build 配置):

    Groovy

      implementation files('my_path/my_lib.aar')
    

    Kotlin

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

如需导入在 Android Studio 之外运行的 Gradle build 的依赖项,请在应用的 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 依赖项,请参阅添加 build 依赖项

声明公开资源

资源包括您项目的 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 应用模块添加对库模块的引用后,您可以设置它们的相对优先级。在构建时,库会按照优先级由低到高的顺序逐一与应用合并。

  • 避免资源合并冲突。

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

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

    为避免资源冲突,请使用非传递 R。如果无法做到这一点,请考虑使用模块独有(或在所有项目模块中具有唯一性)的前缀或其他一致的命名方案。

  • 在多模块构建中,系统会将 JAR 依赖项视为传递依赖项

    在向输出 AAR 的库项目添加 JAR 依赖项时,JAR 会由库模块进行处理,并与其 AAR 打包在一起。

    不过,如果您的项目包含库模块,并且此模块已被应用模块使用,应用模块便会将库的本地 JAR 依赖项视为传递依赖项。在这种情况下,本地 JAR 将由使用它的应用模块进行处理,而不是由库模块进行处理。这会加快库代码更改导致的增量构建的速度。

    由本地 JAR 依赖项导致的所有 Java 资源冲突都必须在使用相应库的应用模块中解决。

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

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

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

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

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

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

    在您构建相关应用模块时,库模块会先编译到 AAR 文件中,然后再添加到应用模块中。因此,每个库都有自己的 R 类,并根据库的软件包名称命名。

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

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

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

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

    如需向库项目添加 ProGuard 规则,请使用 consumerProguardFiles 属性(位于库的 build.gradlebuild.gradle.kts 文件的 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 文件还可包含以下一个或多个可选条目:

  • /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/(用于导出原生库