我的应用程序针对多个市场的应用程序内计费系统具有多种风格。
我有一个库,它共享我所有项目的基本代码。所以我决定将这些支付系统作为产品风味添加到这个库中。
问题是android库可以有产品风味吗?
如果是这样,我如何在应用程序的各个风味中包含不同的风味?
我进行了很多搜索,但找不到有关此场景的任何信息。我在 http://tools.android.com/tech-docs/new-build-system/user-guide 中发现的唯一接近的东西是:
dependencies {
flavor1Compile project(path: ':lib1', configuration: 'flavor1Release')
flavor2Compile project(path: ':lib1', configuration: 'flavor2Release')
}
我将配置更改为不同的东西,但它不起作用!
我正在使用 android studio 0.8.2。
3.4.2
版本并 gradle 到最新的 5.5.1
,它仍然在编译时失败,或者 资源链接失败 在 aapt 中,或 找不到库模块中的符号
最后我发现了如何做到这一点,我将在这里为其他面临同样问题的人解释:
如果 App 和 Library 具有相同的 Flavor 名称
从 Gradle Plugin 3.0.0(及更高版本)开始可以执行以下操作:
库 build.gradle:
apply plugin: 'com.android.library'
// Change below's relative-path
// (as the `../` part is based on my project structure,
// and may not work for your project).
apply from: '../my-flavors.gradle'
dependencies {
// ...
}
android {
// ...
}
项目 build.gradle:
buildscript {
// ...
}
apply plugin: 'com.android.application'
// Note that below can be put after `dependencies`
// (I just like to have all apply beside each other).
apply from: './my-flavors.gradle'
dependencies {
api project(':lib')
}
android {
productFlavors {
// Optionally, configure each flavor.
market1 {
applicationIdSuffix '.my-market1-id'
}
market2 {
applicationIdSuffix '.my-market2-id'
}
}
}
我的口味.gradle:
android {
flavorDimensions 'my-dimension'
productFlavors {
market1 {
dimension 'my-dimension'
}
market2 {
dimension 'my-dimension'
}
}
}
如果 App 或 Library 有不同的 Flavor-name(旧答案)
关键部分是在库 build.gradle
中将 publishNonDefault
设置为 true
,然后您必须按照用户指南的建议定义依赖项。
2022 年更新; publishNonDefault 现在默认为 true,将其设置为 false 将被忽略,因为不推荐使用该选项。
整个项目会是这样的:
库 build.gradle:
apply plugin: 'com.android.library'
android {
....
publishNonDefault true
productFlavors {
market1 {}
market2 {}
market3 {}
}
}
项目 build.gradle:
apply plugin: 'com.android.application'
android {
....
productFlavors {
market1 {}
market2 {}
market3 {}
}
}
dependencies {
....
market1Compile project(path: ':lib', configuration: 'market1Release')
market2Compile project(path: ':lib', configuration: 'market2Release')
// Or with debug-build type support.
android.buildTypes.each { type ->
market3Compile project(path: ':lib', configuration: "market3${type.name}")
}
}
现在您可以选择应用程序风格和构建变体面板,库将被相应地选择,所有构建和运行都将基于所选风格完成。
如果你有多个基于库的应用程序模块 Android Studio 会抱怨 Variant selection conflict ,没关系,忽略它。
https://i.stack.imgur.com/kC8tJ.jpg
Ali 答案有一个问题。我们在构建变体中失去了一个非常重要的维度。如果我们想拥有所有选项(在我的示例中低于 4 (2 x 2)),我们只需在 main module build.gradle 文件中添加 custom configurations 即可使用 Build Variants
中的所有多风格多构建类型。我们还必须在 library module build.gradle 文件中设置 publishNonDefault true。
示例解决方案:
库构建.gradle
android {
publishNonDefault true
buildTypes {
release {
}
debug {
}
}
productFlavors {
free {
}
paid {
}
}
}
应用程序构建.gradle
android {
buildTypes {
debug {
}
release {
}
}
productFlavors {
free {
}
paid {
}
}
}
configurations {
freeDebugCompile
paidDebugCompile
freeReleaseCompile
paidReleaseCompile
}
dependencies {
freeDebugCompile project(path: ':lib', configuration: 'freeDebug')
paidDebugCompile project(path: ':lib', configuration: 'paidDebug')
freeReleaseCompile project(path: ':lib', configuration: 'freeRelease')
paidReleaseCompile project(path: ':lib', configuration: 'paidRelease')
}
Error:java.lang.RuntimeException: Error: more than one library with package name
Android 插件 3.0.0 及更高版本的更新
根据官方 Android 文档 - Migrate dependency configurations for local modules,
通过变体感知依赖解析,您不再需要对本地模块依赖项使用特定于变体的配置,例如 freeDebugImplementation - 插件会为您处理这个您应该按如下方式配置您的依赖项:
dependencies {
// This is the old method and no longer works for local
// library modules:
// debugImplementation project(path: ':library', configuration: 'debug')
// releaseImplementation project(path: ':library', configuration: 'release')
// Instead, simply use the following to take advantage of
// variant-aware dependency resolution. You can learn more about
// the 'implementation' configuration in the section about
// new dependency configurations.
implementation project(':library')
// You can, however, keep using variant-specific configurations when
// targeting external dependencies. The following line adds 'app-magic'
// as a dependency to only the "debug" version of your module.
debugImplementation 'com.example.android:app-magic:12.3'
}
所以在阿里的回答中,改变
dependencies {
....
market1Compile project(path: ':lib', configuration: 'market1Release')
market2Compile project(path: ':lib', configuration: 'market2Release')
}
至
implementation project(':lib')
插件将自动处理特定于变体的配置。希望它有助于其他人将 Android Studio 插件升级到 3.0.0 及更高版本。
我的 Android 插件是 3.4.0,我发现它现在不需要配置。您只需确保应用程序中的 flavorDimensions 和 productFlavors 在库中包含一个相同的 flavorDimensions 和 productFlavors 的 productFlavor。例如:
在 mylibrary 的 build.gradle
apply plugin: 'com.android.library'
android {
....
flavorDimensions "mylibFlavor"
productFlavors {
market1
market2
}
}
应用程序的 build.gradle:
apply plugin: 'com.android.application'
android {
....
flavorDimensions "mylibFlavor", "appFlavor"
productFlavors {
market1 {
dimension "mylibFlavor"
}
market2 {
dimension "mylibFlavor"
}
common1 {
dimension "appFlavor"
}
common2 {
dimension "appFlavor"
}
}
}
dependencies {
....
implementation project(path: ':mylibrary')
}
https://i.stack.imgur.com/ncblI.png
要让风格在 AAR 库上运行,您需要在 Android 库模块的 build.gradle 文件中定义 defaultPublishConfig。
有关详细信息,请参阅:Library Publication。
库发布 默认情况下,库仅发布其发布变体。所有引用该库的项目都将使用此变体,无论它们自己构建哪个变体。由于我们正在努力消除 Gradle 限制,这是一个临时限制。您可以控制发布哪个变体: android { defaultPublishConfig "debug" } 请注意,此发布配置名称引用了完整的变体名称。发布和调试仅适用于没有风味的情况。如果您想在使用风味时更改默认发布的变体,您可以编写: android { defaultPublishConfig "flavor1Debug" }
我还遇到了为各种选项编译模块的问题。
我发现了什么:
看起来我们不需要将 publishNonDefault true
添加到 lib 的 build.gradle
文件中,因为 Gradle 3.0.1。
反编译类 BaseExtension
后发现:
public void setPublishNonDefault(boolean publishNonDefault) {
this.logger.warn("publishNonDefault is deprecated and has no effect anymore. All variants are now published.");
}
而不是:
dependencies {
...
Compile project(path: ':lib', configuration: 'config1Debug')
}
我们应该使用:
dependencies {
...
implementation project(':lib')
}
唯一重要的是,将 configurations {...}
部分添加到 build.gradle
。
因此,应用的 build.gradle
文件的最终变体是:
buildTypes {
debug {
...
}
release {
...
}
}
flavorDimensions "productType", "serverType"
productFlavors {
Free {
dimension "productType"
...
}
Paid {
dimension "productType"
...
}
Test {
dimension "serverType"
...
}
Prod {
dimension "serverType"
...
}
}
configurations {
FreeTestDebug
FreeTestRelease
FreeProdDebug
FreeProdRelease
PaidTestDebug
PaidTestRelease
PaidProdDebug
PaidProdRelease
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(':lib')
...
}
此外,您可以使用 Filter variants 来限制构建变体。
ps 不要忘记在 settings.gradle
文件中包含模块,例如:
include ':app'
include ':lib'
project(':lib').projectDir = new File('app/libs/lib')
目前这是不可能的,尽管如果我没记错的话,这是他们想要添加的功能。 (编辑 2:link、link2)
编辑:目前我使用 defaultPublishConfig
选项来声明发布了哪个库变体:
android {
defaultPublishConfig fullRelease
defaultPublishConfig demoRelease
}
我知道这个主题已经关闭,但只是 gradle 3.0 的更新,请参阅:https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html#variant_aware 和 grep matchingFallbacks
和 missingDimensionStrategy
。现在声明模块风格之间的依赖关系变得更加简单。
...在 gradle3.0 的这种精确情况下,由于风味共享相同的名称,gradle 会神奇地映射它们,不需要配置。
在这个情况下。我如何导入特定构建的依赖项。例如:market1Common1Debug market1Common1DebugImplementation 'androidx.appcompat:1.2.0'
https://i.stack.imgur.com/hk2ya.png