通过发布内容变体,您可以为用户打造更个性化的体验。通过配置发布内容变体,您可以发布不同的 build 变体,并且每个 build 变体都具有自己的属性。
如果您发布多个库 build 变体,用户就可以选择适合其需求的功能。例如,您可以针对调试与发布 build 类型发布不同的工件。调试发布内容工件可以添加额外的日志记录代码,以及用于启用此额外日志记录功能的不同依赖项。
在继续之前,请确保已准备好要发布的库。
使用 Gradle 模块元数据
您必须使用 Gradle 模块元数据 (GMM) 才能发布库的变体。 GMM 用于描述您的发布内容,以及进行变体感知依赖项管理。 默认情况下,GMM 会与您的库一起发布。
使用 GMM 的优势包括:
- 如果您将 GMM 和 Gradle 6.0 或更高版本结合使用,即可发布多个发布内容变体或多个工件,并且每个变体或工件都具有自己的属性和依赖项。 如果您使用 Maven 的 POM 文件 那么您只能发布一个工件如果您使用的是 POM 文件,则可以使用分类器发布其他工件,但这些工件无法设置自己的依赖项。
- Gradle 会自动创建一个编译专用变体和一个运行时专用变体,并且每个变体都具有自己的依赖项。您可以发布一个编译专用变体和一个运行时专用变体,以便使用方能够根据他们使用库的时间来选择适用的变体。GMM 可让消费者查看用于编译和
在运行时使用,具体取决于已发布的库对
api
、implementation
或compileOnly
/runtimeOnly
。请参阅 依赖项配置 获取完整的依赖项列表。即使您发布单个发布内容变体,也可以这样。 - 使用测试固件时,您可以发布具有特殊 元数据或 功能 以供消费者选择即使您发布单个发布内容变体,也可以这样。
了解发布内容变体
若要了解发布内容变体的工作原理,建议您先熟悉一下 Gradle 的 基本发布步骤。 以下是一些发布内容的关键概念:
- build 变体:Gradle 用于构建库的配置,它是 build 类型和产品变种的交叉产物。如需了解详情,请参阅 Android build 术语表。
- 工件:由 build 生成的文件或目录。就库发布而言,工件通常是 JAR 或 AAR 文件。
- 发布内容变体:工件及其关联的属性、功能和依赖项。请注意,Gradle 将发布内容变体称为“变体”。不过,在这些文档中,我们称之为“发布内容变体”,以将其与“build 变体”区分开。
- 属性:当有多个选项时,Gradle 会使用属性来识别和选择发布内容变体。例如,
org.gradle.usage=java-api
和org.gradle.jvm.version=11
是变体属性。 - 软件组件:可以包含一个或多个发布内容变体,并会发布到一组 Maven 坐标 (
groupdId:artifactId:version
) 的 Gradle 对象。软件组件是通过Project.getComponents()
在 Gradle 的 DSL 中提供的。 - 发布内容:发布到代码库并供使用方使用的内容。发布内容由一个软件组件及其元数据(例如,其身份 [
groupId:artifactId:version
])组成。
Android Gradle 插件 (AGP) 7.1 引入了网域专用语言 (DSL),以控制在发布期间使用哪些 build 变体以及忽略哪些 build 变体。借助 DSL,您可以创建包含以下内容之一的 SoftwareComponent
实例:
- 来自一个 build 变体的一个发布内容变体
- 来自多个 build 变体的多个发布内容变体
创建具有多个发布内容变体的软件组件时,AGP 会为每个变体设置属性,以便使用者能够选择自己需要的适当变体。这些属性直接来自用于创建 build 变体的 build 类型和变种。创建具有单个发布内容变体的组件不需要属性,因为不需要进行任何区分。
创建具有单个发布内容变体的软件组件
以下代码段会使用从 release
build 变体创建的单个发布内容变体来配置软件组件,并将源代码 JAR 添加为辅助工件:
Kotlin
android { publishing { singleVariant("release") { withSourcesJar() } } }
Groovy
android { publishing { singleVariant('release') { withSourcesJar() } } }
您可以创建多个组件,每个组件都包含一个发布内容变体,并在不同 Maven 坐标下分发这些组件。在这种情况下,发布内容变体上不会设置任何属性。您无法通过查看发布内容元数据来判断此发布内容变体是否来自 release
build 变体。由于只涉及一个发布内容变体,因此无需消除歧义。
创建具有多个发布内容变体的软件组件
您可以选择将全部或部分 build 变体放入单个软件组件。AGP 会自动使用 build 类型名称、产品变种名称和产品变种维度名称来创建属性,以便使用方项目能够将它们区分开。
如需在单个组件中发布所有 build 变体,请在模块级 build.gradle
文件的 multipleVariants{}
代码块中指定 allVariants()
:
Kotlin
android { publishing { multipleVariants { allVariants() withJavadocJar() } } }
Groovy
android { publishing { multipleVariants { allVariants() withJavadocJar() } } }
这会创建一个名为 default
的组件。如需将您的组件命名为其他名称,请使用 multipleVariants({name})
。在这种情况下,系统会将所有 build 类型和产品变种维度都用作属性。
您也可以使用 includeBuildTypeValues()
和 includeFlavorDimensionAndValues()
来选择要发布哪些变体:
Kotlin
android { publishing { multipleVariants("custom") { includeBuildTypeValues("debug", "release") includeFlavorDimensionAndValues( dimension = "color", values = arrayOf("blue", "pink") ) includeFlavorDimensionAndValues( dimension = "shape", values = arrayOf("square") ) } } }
Groovy
android { publishing { multipleVariants('custom') { includeBuildTypeValues('debug', 'release') includeFlavorDimensionAndValues( /*dimension =*/ 'color', /*values =*/ 'blue', 'pink' ) includeFlavorDimensionAndValues( /*dimension =*/ 'shape', /*values =*/ 'square' ) } } }
在此示例中,自定义组件包含 build 类型的 (debug
, release
)、维度 color
的 (blue
, pink
) 和维度 shape
的 (square
) 的所有组合。
必须列出所有变种维度,即使您只发布某个维度中的一个值也是如此,以便 AGP 知晓要为每个维度使用哪个值。
下表列出了生成的发布内容变体及其关联的属性。
变体 | 属性 |
---|---|
blueSquareDebug | com.android.build.api.attributes.BuildTypeAttr ="debug"
com.android.build.api.attributes.ProductFlavorAttr:color ="blue" |
blueSquareRelease |
com.android.build.api.attributes.BuildTypeAttr="release"
|
pinkSquareDebug |
com.android.build.api.attributes.BuildTypeAttr="debug"
|
pinkSquareRelease |
com.android.build.api.attributes.BuildTypeAttr="release"
|
实际上,我们会发布更多变体。例如,上述每个变体都会发布两次,一次用于编译,另一次用于运行时;它们具有不同的依赖项(基于声明的依赖项使用的是 implementation
还是 api
),其属性 org.gradle.Usage
的值也各不相同。不过,这两个变体的工件(AAR 文件)是相同的。
如需了解详情,请参阅 publishing
API 文档。
发布多变种库时的兼容性问题
使用 AGP 7.0 或更低版本的项目无法使用已发布的多变种库
使用 AGP 7.1 或更高版本。这是一个由更改属性导致的已知问题
产品变种维度的名称(从 dimensionName
到)
com.android.build.api.attributes.ProductFlavor:dimensionName
(在 AGP 7.1 中)。
您可以在以下位置使用 missingDimensionStrategy
,具体取决于您的项目设置:
旧版 Variant API 一起运行
。
例如,假设您的应用项目只有一个版本产品 变种维度:
Kotlin
android {
applicationVariants.forEach { variant ->
val flavor = variant.productFlavors[0].name
val attributePrefix = "com.android.build.api.attributes.ProductFlavor"
val dimensionName = "version"
variant.missingDimensionStrategy("$attributePrefix:$dimensionName", flavor)
}
}
Groovy
android {
applicationVariants.forEach { variant ->
def flavor = variant.getProductFlavors()[0].name
def attributePrefix = "com.android.build.api.attributes.ProductFlavor"
def dimensionName = "version"
variant.missingDimensionStrategy("$attributePrefix:$dimensionName", flavor)
}
}