基于Android Gradle中的多样式库的多样式应用


102

我的应用程序针对几种市场的应用程序计费系统具有多种风格。

我有一个共享所有项目基本代码的库。因此,我决定将这些付款系统作为产品口味添加到该库中。

问题是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。


经过多次搜索后,我发现没有办法实现此目的,即使我将android插件升级到最新3.4.2版本并升级到最新版本5.5.1,它仍然会因编译时间而失败,或者在aapt中资源链接失败,或者找不到库中的符号模块
VinceStyling '19

Answers:


141

最后,我了解了如何执行此操作,在这里我将向面临相同问题的其他人进行解释:

关键部分是在库build.gradle中将publishNonDefault设置为true,然后必须按照用户指南的建议定义依赖项。

整个项目如下:

库build.gradle:

apply plugin: 'com.android.library'

android {        
    ....
    publishNonDefault true
    productFlavors {
        market1 {}
        market2 {}
    }
}

项目build.gradle:

apply plugin: 'com.android.application'

android {
    ....
    productFlavors {
        market1 {}
        market2 {}
    }
}

dependencies {
    ....
    market1Compile project(path: ':lib', configuration: 'market1Release')
    market2Compile project(path: ':lib', configuration: 'market2Release')
}

现在,您可以选择应用程序样式和“构建变体”面板,并且将相应地选择库,并且所有构建和运行都将基于选定的样式进行。

如果您有多个基于库的应用模块,则Android Studio会抱怨Variant选择冲突,可以,请忽略它。

在此处输入图片说明


感谢您的共享,现在我可以摆脱defaultPublishConfig解决方法了。
Delblanco 2014年

2
在AS 1.1.0上运行,上述解决方案似乎仍然可以使用,但是1)调试/发布版本选择丢失了,我似乎在库中发现AIDL的问题经常无法生成适当的代码。有什么想法吗?
2015年

1
@IgorGanapolsky buildTypes与此无关。每种类型都有所有构建类型(通常是调试和发布),并且所有这些都可以使用此方法。
阿里

1
@ An-droid定义了用于market1风格的库!
阿里

1
为什么将其设置为“发布”构建类型?在调试构建期间是否选择了“发布”构建类型?
WindRider

35

阿里答案有一个问题。我们在构建变体中失去了一个非常重要的方面。如果我们想拥有所有选项(在我的示例中为4(2 x 2)以下),我们只需在主模块build.gradle文件中添加自定义配置即可使用中的所有多样式multi-buildType 。我们还必须在库模块build.gradle文件中将publishNonDefault设置为trueBuild Variants

解决方案示例:

库build.gradle

android {

    publishNonDefault true

    buildTypes {
        release {
        }
        debug {
        }
    }
    productFlavors {
        free {
        }
        paid {
        }
    }
}

应用程式build.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,occoured
扯谈乔希

21

Android插件3.0.0及更高版本的更新

根据官方的Android文档- 迁移本地模块的依赖项配置

通过变体感知的依赖关系解析,您不再需要使用特定于变体的配置(例如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及更高版本。


7

我的Android插件为3.4.0,我发现它现在不需要配置。您需要确保应用程序中的flavorDimensions和productFlavors在库中包含一个具有相同flavorDimensions和productFlavors的productFlavor。例如:

在图书馆的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')
}

同步后,您可以在“构建变体”窗口中切换所有选项: 在此处输入图片说明


但是,如果我不想在主应用程序模块中使用相同的样式,该怎么办?假设我有多个具有各自特定风格的应用程序模块和一个具有各自特定风格的通用模块,并且我想在我的应用程序中使用具有特定风味的lib。你会怎么做?将我的lib风格复制到所有应用程序没有任何意义。
比尔达

@Billda您不需要全部复制,只需将一个相同的产品保存在应用程序中,对于我的示例,我可以将market1或market2保留在应用程序的build.gradle中。
JiajiaGu

2

为了使口味在AAR库上运行,您需要在Android库模块的build.gradle文件中定义defaultPublishConfig。

有关更多信息,请参见:图书馆出版物

图书馆出版

默认情况下,库仅发布其发行版本。不论它们自己构建哪种变体,所有引用该库的项目都将使用此变体。由于我们正在努力移除的Gradle限制,因此这是一个临时限制。您可以控制要发布的变体:

android {defaultPublishConfig“ debug”}

请注意,此发布配置名称引用完整的变体名称。发布和调试仅在没有风味时适用。如果要在使用调味料时更改默认的已发布变体,则应编写:

android {defaultPublishConfig“ flavor1Debug”}


1

目前还无法实现,尽管如果我正确记得它想要添加的功能。(编辑2:linklink2

编辑:目前,我正在使用该defaultPublishConfig选项来声明要发布的库变体:

android {
    defaultPublishConfig fullRelease
    defaultPublishConfig demoRelease 
}

1
因此,每次我要编译应用程序时,都必须在库的build.gradle中更改此设置?
阿里

好吧,是的。。。每次您想以不同的风格来编译应用程序。
Delblanco 2014年

实际上,当我为库模块定义口味时,未在应用模块中找到继承的R包。
阿里

您是否在AS中同步了gradle文件?
Delblanco 2014年

@Delblanco这看起来像体力劳动,而且非常脆弱(开发人员很懒,忘记修改他们的build.gradle文件)。
IgorGanapolsky

1

我知道这个主题已经关闭,但是仅使用gradle 3.0进行了更新,请参见:https : //developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html#variant_aware和grep matchingFallbacksmissingDimensionStrategy。现在,更轻松地声明模块风味之间的依赖关系。

...并且在gradle3.0的这种精确情况下,由于口味具有相同的名称,因此gradle会神奇地将它们映射,因此不需要任何配置。


对我而言,似乎跳过了运行时生成的内容。作为示例,simonvt->原理图生成对我而言不再适用于新方法。:-/
Stefan Sprenger's

1

我还遇到了各种选项的模块编译问题。

我发现的是:

Gradle 3.0.1开始,看来我们不需要添加publishNonDefault true到lib的build.gradle文件中。

反编译一个类后,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')
   ...
}

另外,您可以使用筛选器变体来限制构建变体。

PS不会忘记在settings.gradle文件中包含模块,例如:

include ':app'
include ':lib'
project(':lib').projectDir = new File('app/libs/lib')

先生,您能否解释一下该凭单将如何确定天气,以将图书馆包含在特定配置中?我的意思是说我有一种情况,当我需要为某种风味使用某些lib,但我不需要为其他风味使用它时
Jenya Kirmiza

没有陷入这种情况。但是,谷歌教程developer.android.com/studio/build/dependencies建议在“ dependencies {...}”块中的“ implementation”命令前添加前缀。即依赖项{paidImplementation project(':lib')},或依赖项{debugImplementation project(':lib')},或任何多个变体组合依赖项{paidProdDebugImplementation project(':lib')}。检查一下并给我们反馈:)
Sergio'Sep
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.