使用融合库将多个 Android 库发布为一个库

在包含许多模块的项目中,在尝试维护清晰的项目结构的同时,向用户分发 Android 库可能具有挑战性。 在许多情况下,需要发布的库比预期的要多得多。

与 Android Gradle 插件捆绑在一起的 Fused Library 插件可帮助将多个 Android 库模块打包到单个可发布的 Android 库中。这样,您就可以根据需要在 build 中对库的源代码和资源进行模块化,同时避免在分发后暴露项目的结构。

作为单个库进行分发具有以下优势:

  • 简化依赖项:用单个 AAR 替换多个库依赖项,从而为用户简化项目设置和版本管理
  • 库大小缩减:可能会改进代码缩减,从而减小 AAR
  • 安全性更高:可以更好地控制已发布库的内部实现细节

创建融合库

如需构建融合库,您必须创建新的 Android 模块、添加依赖项,然后发布融合库。

前提条件

如需使用 Fused Library 插件,请使用 AGP 9.0 或更高版本。 旧版 Fused Library 插件具有不同的行为和问题,这些问题已在 AGP 9.0 中得到修复。

添加新的融合库模块

如需使用该插件,您必须向项目中添加一个新的 Android 模块:

在此示例中,合并库模块将命名为 myFusedLibrary。

  1. 将 include(":myFusedLibrary") 附加到 settings.gradle.kts 文件。
  2. 在 gradle/libs.versions.toml 文件的 [plugins] 部分下添加 android-fusedlibrary = { id = "com.android.fused-library", version.ref = "agp" }。
  3. 在顶级 build.gradle.kts 文件的 plugins 代码块中添加 alias(libs.plugins.android.fusedlibrary) apply false。
  4. 如需创建 myFusedLibrary 模块,请创建一个名为 myFusedLibrary 的新目录(右键点击“My Application”>“New”>“Directory”)。
  5. 在 myFusedLibrary 模块中创建一个 build.gradle.kts 文件(右键点击 myFusedLibrary 模块 >“新建”>“文件”)。
  6. 将以下内容粘贴到 myFusedLibrary/build.gradle.kts 文件中:

Kotlin

plugins {
    alias(libs.plugins.android.fusedlibrary)
    `maven-publish`
}

androidFusedLibrary {
    namespace = "com.example.myFusedLibrary"
    minSdk = 21
}

dependencies { }

Groovy

plugins {
    id 'com.android.fused-library'
}

androidFusedLibrary {
    namespace 'com.example.myFusedLibrary'
    minSdk 21
}

dependencies {

}

添加依赖项

融合库的核心功能是捆绑依赖项。该插件支持添加本地项目依赖项和外部库。如需指定要打包的依赖项,请使用 include 配置。 传递依赖项不会打包。

例如:

Kotlin

dependencies {
    include(project(":image-rendering"))
    include("mycoolfonts:font-wingdings:5.0")
}

Groovy

dependencies {
    include project(':image-rendering')
    include 'mycoolfonts:font-wingdings:5.0'
}

发布融合库

在发布融合库之前,您应先熟悉如何发布 Android 库。发布融合库与发布 Android 库类似,但您必须考虑一些关键差异,才能正确发布融合库:

  • Maven Publish 插件还必须应用于任何已应用 Fused Library 插件的模块。
  • 发布内容必须继承自 fusedLibraryComponent,因为这会提供编译融合库工件所需的依赖项。

以下是发布配置示例:

Kotlin

plugins {
    alias(libs.plugins.android.fusedlibrary)
    `maven-publish`
}

androidFusedLibrary { … }

dependencies { … }

publishing {
    publications {
        register<MavenPublication>("release") {
             groupId = "my-company"
             artifactId = "my-fused-library"
             version = "1.0"
             from(components["fusedLibraryComponent"])
        }
    }
}

Groovy

plugins {
    id 'com.android.fused-library'
    id 'maven-publish'
}

androidFusedLibrary { … }

dependencies { … }

publishing {
    publications {
        release(MavenPublication) {
            groupId = "my-company"
            artifactId = "my-fused-library"
            version = "1.0"
            afterEvaluate {
            from components.fusedLibraryComponent
        }
    }
}

发布融合库以进行测试

您应测试依赖于 Android 应用或 Android 库中已发布的融合库。建议的方法是将合并库及其项目依赖项发布到本地 Maven 仓库。

如需将合并库工件发布到本地代码库,请定义类似于以下内容的配置:

Kotlin

plugins {
    alias(libs.plugins.android.fusedlibrary)
    `maven-publish`
}

repositories {
    maven {
        name = "myLocalRepo"
        url = uri(layout.buildDirectory.dir("myLocalRepo"))
    }
}

Groovy

plugins {
    id 'com.android.fused-library'
    id 'maven-publish'
}

repositories {
    maven {
        name 'myLocalRepo'
        url layout.buildDirectory.dir('myLocalRepo')
    }
}

上传融合库

如需分发融合库,请参阅上传库。

行为和保护措施

合并 Android 库的过程非常复杂,这可能会使插件难以推断优先级。例如,如果两个库具有相同的类路径,则在融合库时会导致构建失败。在不同库中选择同名资源时,资源合并会考虑指定的依赖项顺序。

  • 合并库只能作为 Android 库工件 AAR 发布,以便作为依赖项添加。
  • 不支持融合使用数据绑定的库。
  • 您无法在单个融合库中融合多种 build 类型和产品变种。为不同的变体创建单独的融合库。

为了平衡所需的配置量和易用性,插件会在出现不明确的冲突时导致构建失败,或者在融合工件时使用启发法。下表详细说明了工件的融合方式:

类型 行为
类 具有相同类路径的库会在融合库时导致 build 失败。
Android资源 在选择不同位置的同名资源时,资源合并会考虑指定的依赖项顺序。
AAR 元数据 AAR 元数据版本会通过优先考虑每个依赖项库中的最高值来进行合并。我们提供了一个 DSL 来替换这些值。

Kotlin

 androidFusedLibrary { aarMetadata { minCompileSdk = 21 minCompileSdkExtension = 1 } }
Java 资源 不允许在多个库中存在路径相同的 Java 资源文件,否则会导致构建失败。

已知问题

Fused Library 是一个新插件,存在一些已知问题,我们正在努力解决这些问题,以满足所有用例的需求。您可以针对遇到的任何问题报告 bug。

  • 问题 #454305444:如果库包含不叫“proguard.txt”的使用方 ProGuard 规则,会导致 build 失败。 已在 AGP 9.1 及更高版本中修复。
  • 问题 #374982739:添加对其他 .aar 文件的文件依赖项
  • 问题 #231433225:不支持融合 RenderScript 和 Prefab 工件

了解融合库的依赖项

合并库没有源代码,实际上仅使用 Android 库作为其唯一来源,因此请务必了解每个部分来自何处。如需列出合并到生成的工件中的依赖项以及构建该工件所需的依赖项,请对融合库运行 gradle :report 任务。该任务会生成一个 JSON 报告,并将其保存在融合库的 build/reports 目录中。

如需详细了解内部插件依赖项,请运行 gradle :dependencies 任务以查看插件配置的状态。