配置产品变种productFlavors matchingFallbacks missingDimensionStrategy

google 文档说明 对应地址: https://developer.android.com/studio/build/build-variants#product-flavors

构建依赖项

matchingFallbacks 作用

疑惑:flavor是干什么的,怎么用?
flavor 风味的意思,在app 打包过程中,除了debug和 release 这两种基本版本外,flavor 提供了多种打包风格,每个产品风格 productFlavors 都必须有一个风格与其对应。 打包的时候会按照 风格维度(包含的产品风格个数)风格维度(包含的产品风格个数)..*2(debug ,release)
。其能提供覆盖defaultConfig 相同的属性,产生多种变体。

matchingFallbacks :module B 依赖moduleA,moduleB 中的 flavor 与 module A 中的所有 flavor 都不匹配, 可以通过 matchingFallbacks 指定. matchingFallbacks = ['debug', 'qa', 'release'] 选所有。
参考:

android 项目中gradle 的学习

missingDimensionStrategy属性的第一个值为dimension维度,后面的Strings为该维度下的渠道flavors。
参考:
flavorDimensions多维度理解
FlavorDimensions,构建变体

创建产品变种与创建构建类型类似:将其添加到构建配置中的 productFlavors 代码块并添加所需的设置。产品变种支持与 defaultConfig 相同的属性,这是因为,defaultConfig 实际上属于 ProductFlavor 类。这意味着,您可以在 defaultConfig 代码块中提供所有变种的基本配置,每个变种均可更改其中任何默认值,如 applicationId。如需详细了解应用 ID,请参阅设置应用 ID

注意:您仍然需要在 main/ 清单文件中使用 package 属性指定软件包名称。此外,您还必须在源代码中使用该软件包名称引用 R 类,或解析任何相关的 Activity 或服务注册。这样,您就可以使用 applicationId 为每个产品变种指定一个唯一的 ID,以用于打包和分发,而不必更改源代码。

所有变种都必须属于一个指定的变种维度,即一个产品变种组。您必须将所有变种分配给某个变种维度;否则,您将收到如下所示的构建错误。如果给定的模块仅指定一个变种维度,则 Android Gradle 插件会自动将该模块的所有变种分配给该维度。

 Error:All flavors must now belong to a named flavor dimension.
  The flavor 'flavor_name' is not assigned to a flavor dimension.

提示:插件会尝试将应用的变体与本地库依赖项的变体进行匹配。由于变体感知型依赖项匹配机制依赖于您为变种维度命名的方式,因此您应谨慎地为变种维度命名。这样做可让您更好地控制来自本地依赖项的哪些代码和资源与应用的各个版本匹配。

以下代码示例创建了一个名为“version”的变种维度,并添加了“demo”和“full”产品变种。这些变种提供了它们自己的 applicationIdSuffixversionNameSuffix

android {
    ...
    defaultConfig {...}
    buildTypes {
        debug{...}
        release{...}
    }
    // Specifies one flavor dimension.
翻译为:
指定一种风味维度。
    flavorDimensions "version"
    productFlavors {
        demo {
            // Assigns this product flavor to the "version" flavor dimension.
            // If you are using only one dimension, this property is optional,
            // and the plugin automatically assigns all the module's flavors to
            // that dimension.
翻译后:
 "version" 产品维度分配不同风格。如果只使用一个维度,则此属性是可选的,并且插件会自动将模块的所有风格分配给那个维度

            dimension "version"
            applicationIdSuffix ".demo"
            versionNameSuffix "-demo"
        }
        full {
            dimension "version"
            applicationIdSuffix ".full"
            versionNameSuffix "-full"
        }
    }
}

注意:如需在 Google Play 中使用多 APK 支持分发应用,请将相同的 applicationId 值赋予所有变体,并为每个变体指定一个不同的 versionCode。如需在 Google Play 中以独立应用的形式分发应用的不同变体,您需要为每个变体分配一个不同的 applicationId

创建并配置产品变种后,点击通知栏中的 Sync Now。同步完成后,Gradle 会根据构建类型和产品变种自动创建构建变体,并按照 <product-flavor><Build-Type> 为其命名。例如,如果您创建了“demo”和“full”产品变种,并保留了默认的“debug”和“release”构建类型,则 Gradle 会创建以下构建变体:
demoDebug
demoRelease
fullDebug
fullRelease
您可以将构建变体更改为您要构建并运行的任意变体,只需依次转到 Build > Select Build Variant,然后从下拉菜单中选择一个变体即可。不过,如需开始使用每个构建变体自己的功能和资源对其进行自定义,您需要知道如何创建和管理源代码集

将多个产品变种与变种维度组合在一起

在某些情况下,您可能要将多个产品变种的配置组合在一起。例如,您可能要为基于 API 级别的“full”和“demo”产品变种创建不同的配置。为此,您可以使用 Android Plugin for Gradle 创建多组产品变种作为变种维度。在构建应用时,Gradle 会将您定义的每个变种维度中的产品变种配置以及构建类型配置组合在一起,以创建最终的构建变体。Gradle 不会将属于同一变种维度的产品变种组合在一起。

如需根据 ABI 和屏幕密度为应用创建不同的版本,您应构建多个 APK,而不要使用产品变种。

以下代码示例使用 flavorDimensions 属性创建“mode”变种维度和“api”变种维度,前者用于对“full”和“demo”产品变种进行分组,后者用于根据 API 级别对产品变种配置进行分组:

android {
  ...
  buildTypes {
    debug {...}
    release {...}
  }

  // Specifies the flavor dimensions you want to use. The order in which you
  // list each dimension determines its priority, from highest to lowest,
  // when Gradle merges variant sources and configurations. You must assign
  // each product flavor you configure to one of the flavor dimensions.
翻译后:
指定你要使用的风味维度。当Gradle合并变体源和配置时,需要从最高到最低列出每个维度确定其优先级。
您必须为每种口味维度分配每种产品口味 。
  flavorDimensions "api", "mode"

  productFlavors {
    demo {
      // Assigns this product flavor to the "mode" flavor dimension.
翻译后:
将此产品风味分配给“模式”风味维度
      dimension "mode"
      ...
    }

    full {
      dimension "mode"
      ...
    }

    // Configurations in the "api" product flavors override those in "mode"
    // flavors and the defaultConfig block. Gradle determines the priority
    // between flavor dimensions based on the order in which they appear next
    // to the flavorDimensions property above--the first dimension has a higher
    // priority than the second, and so on.
翻译后:
 配置“api”产品风格覆盖“ mode”中的风格和默认配置块。Gradle确定风味维度之间优先级标准,是基于它们出现在上面的flavourDimensions风格维度属性的顺序,第一个维度优先级高于第二个,依此类推。
    minApi24 {
      dimension "api"
      minSdkVersion 24
      // To ensure the target device receives the version of the app with
      // the highest compatible API level, assign version codes in increasing
      // value with API level. To learn more about assigning version codes to
      // support app updates and uploading to Google Play, read Multiple APK Support
翻译后:
为了确保目标设备通过应用兼容最高的API级别版本,采用以递增分配版本代码方式。
要了解有关将代码版本,应用更新并上传到Google Play的更多信息,请阅读多个APK支持。
      versionCode 30000 + android.defaultConfig.versionCode
      versionNameSuffix "-minApi24"
      ...
    }

    minApi23 {
      dimension "api"
      minSdkVersion 23
      versionCode 20000  + android.defaultConfig.versionCode
      versionNameSuffix "-minApi23"
      ...
    }

    minApi21 {
      dimension "api"
      minSdkVersion 21
      versionCode 10000  + android.defaultConfig.versionCode
      versionNameSuffix "-minApi21"
      ...
    }
  }
}
...

Gradle 创建的构建变体数量等于每个变种维度中的变种数量与您配置的构建类型数量的乘积。当 Gradle 为每个构建变体或对应的 APK 命名时,先显示属于较高优先级变种维度的产品变种,接着是较低优先级维度中的产品变种,再接着是构建类型。以上面的构建配置为例,Gradle 使用以下命名方案创建了总共 12 个构建变体:(eg. 322=12 是乘积的关系)

构建变体:[minApi24, minApi23, minApi21][Demo, Full][Debug, Release]
对应的 APK:app-[minApi24, minApi23, minApi21]-[demo, full]-[debug, release].apk

例如,
构建变体:minApi24DemoDebug
对应的 APK:app-minApi24-demo-debug.apk

除了可以为各个产品变种和构建变体创建源代码集目录之外,您还可以为产品变种的每个组合创建源代码集目录。例如,您可以创建 Java 源代码并将其添加到 src/demoMinApi24/java/ 目录中,只有在构建将这两个产品变种组合在一起的变体时,Gradle 才会使用这些源代码。您为产品变种组合创建的源代码集的优先级高于属于各个产品变种的源代码集。如需详细了解源代码集以及 Gradle 如何合并资源,请参阅关于如何创建源代码集的部分。

过滤变体

Gradle 会为您配置的产品变种和构建类型的每种可能组合创建一个构建变体。不过,某些构建变体可能并不是您需要的,或者对于您的项目来说没有意义。您可以在模块级 build.gradle 文件中创建变体过滤器,以移除某些构建变体配置。

以上一部分中的构建配置为例,假设您打算让“demo”版应用仅支持 API 级别 23 及更高级别。您可以使用 [`variantFilter`](https://google.github.io/android-gradle-dsl/current/com.android.build.api.variant.VariantFilter.html) 代码块过滤掉所有将“minApi21”和“demo”产品变种组合在一起的构建变体配置:

android {
  ...
  buildTypes {...}

  flavorDimensions "api", "mode"
  productFlavors {
    demo {...}
    full {...}
    minApi24 {...}
    minApi23 {...}
    minApi21 {...}
  }

  variantFilter { variant ->
      def names = variant.flavors*.name
      // To check for a certain build type, use variant.buildType.name == "<buildType>"
翻译后:
要检查特定的构建类型,请使用variant.buildType.name ==“ <buildType>”
      if (names.contains("minApi21") && names.contains("demo")) {
          // Gradle ignores any variants that satisfy the conditions above.
翻译后:
Gradle会忽略满足上述条件的所有变体
          setIgnore(true)
      }
  }
}
...

引用

使用变体感知型依赖项管理机制

missingDimensionStrategy属性的第一个值为dimension维度,后面的Strings为该维度下的渠道flavors。我们可以看下它的函数原型

Android 插件 3.0.0 及更高版本包含一种新的依赖项机制,该机制可在使用库时自动匹配变体。这意味着,应用的 debug 变体会自动使用库的 debug 变体,依此类推。在使用变种时,这种机制也同样适用 - 应用的 freeDebug 变体将使用库的 freeDebug 变体。

为了让插件准确匹配变体,您需要在无法进行直接匹配的情况下提供匹配回退机制。不妨假设您的应用配置了一个名为“staging”的构建类型,但该应用的一个库依赖项没有进行相应配置。当插件尝试构建“staging”版本的应用时,它不知道要使用哪个版本的库,因此您将看到一条与以下内容类似的错误消息:

Error:Failed to resolve: Could not resolve project :mylibrary.
Required by:
    project :app

解决与变体匹配相关的构建错误

插件包含一些 DSL 元素,这些元素有助于控制 Gradle 应如何解决应用与依赖项之间无法进行直接变体匹配的问题。请参阅下表,以确定应使用哪个 DSL 属性来解决与变体感知依赖项匹配相关的特定编译错误。

eg .missingDimensionStrategy 'minApi', 'minApi18', 'minApi23' //优先使用依赖库 minApi 下的 minApi18
missingDimensionStrategy 'abi', 'x86', 'arm64' //优先使用依赖库 abi 下的 x86

1. 编译错误及解决方案
您的应用包含库依赖项不包含的构建类型。
例如,您的应用包含“staging”版本类型,但依赖项仅包含“debug”和“release”版本类型。
请注意,如果库依赖项包含您的应用不包含的编译类型,这不会引发问题。这是因为,插件在任何时候都不会从依赖项请求该构建类型。

方案:
使用 matchingFallbacks 为给定的构建类型指定替代匹配,如下所示:



// In the app's build.gradle file.
android {
    buildTypes {
        debug {}
        release {}
        staging {
            // Specifies a sorted list of fallback build types that the
            // plugin should try to use when a dependency does not include a
            // "staging" build type. You may specify as many fallbacks as you
            // like, and the plugin selects the first build type that's
            // available in the dependency.
翻译后:
指定后备构建类型的排序列表, 插件在不包含依赖项时应尝试使用 “ staging”构建类型。
您可以指定与您一样多你喜欢的后备广告,然后插件在依赖项中可选择第一个构建类型 。
       
            matchingFallbacks = ['debug', 'qa', 'release']
        }
    }
}

2. 对于应用及其库依赖项中均存在的给定变种维度,您的应用包含库不包含的变种。
例如,您的应用及其库依赖项都包含“tier”变种维度。不过,应用中的“tier”维度包含“free”和“paid”变种,但依赖项中的同一维度仅包含“demo”和“paid”变种。

请注意,对于应用及其库依赖项中均存在的给定变种维度,如果库包含您的应用不包含的产品变种,这不会引发问题。这是因为,插件在任何时候都不会从依赖项请求该变种。

使用 matchingFallbacks 为应用的“free”产品变种指定替代匹配,如下所示:


// In the app's build.gradle file.
android {
    defaultConfig{
    // Do not configure matchingFallbacks in the defaultConfig block.
    // Instead, you must specify fallbacks for a given product flavor in the
    // productFlavors block, as shown below.
翻译后:
不要在defaultConfig块中配置matchFallbacks。 相反,您必须在 productFlavors块 给定fallbacks,如下所示。
  }
    flavorDimensions 'tier'
    productFlavors {
        paid {
            dimension 'tier'
            // Because the dependency already includes a "paid" flavor in its
            // "tier" dimension, you don't need to provide a list of fallbacks
            // for the "paid" flavor.
翻译后:
因为依赖项已在“层”维度的依赖项中包含“付费”形式, 对于“付费”口味您无需提供后备列表。
        }
        free {
            dimension 'tier'
            // Specifies a sorted list of fallback flavors that the plugin
            // should try to use when a dependency's matching dimension does
            // not include a "free" flavor. You may specify as many
            // fallbacks as you like, and the plugin selects the first flavor
            // that's available in the dependency's "tier" dimension.
翻译后:
在不包含“免费”的味道插件时候,后备味道的排序列表 应该在依赖项的匹配维度确实起作用时。您可以 根据需要指定尽可能多的后备fallbacks,然后在依赖项的“tier”维度中可用的第一个样式插件。
            matchingFallbacks = ['demo', 'trial']
        }
    }
}

3. 库依赖项包含您的应用不包含的变种维度。
例如,库依赖项包含“minApi”维度的变种,但您的应用仅包含“tier”维度的变种。因此,当您要构建“freeDebug”版本的应用时,插件不知道是使用“minApi23Debug”还是“minApi18Debug”版本的依赖项。
请注意,如果您的应用包含库依赖项不包含的变种维度,这不会引发问题。这是因为,插件只会匹配依赖项中存在的维度的变种。例如,如果依赖项不包含 ABI 的维度,“freeX86Debug”版本的应用将直接使用“freeDebug”版本的依赖项。

在 defaultConfig 代码块中使用 missingDimensionStrategy 指定插件应从每个缺失维度中选择的默认变种,如以下示例所示。您也可以替换在 productFlavors 代码块中的选择,让每一个变种都可以为缺失维度指定一个不同的匹配策略。


// In the app's build.gradle file.
android {
    defaultConfig{
    // Specifies a sorted list of flavors that the plugin should try to use from
    // a given dimension. The following tells the plugin that, when encountering
    // a dependency that includes a "minApi" dimension, it should select the
    // "minApi18" flavor. You can include additional flavor names to provide a
    // sorted list of fallbacks for the dimension.
翻译后:
插件应尝试从一个维度使用一组指定的口味的排序列表。下面告诉插件,当遇到 包含“ minApi”维的依赖项,应选择 “ minApi18”风味。您可以包括其他风味名称以提供 维度的后备列表排序

    missingDimensionStrategy 'minApi', 'minApi18', 'minApi23'
  丢失维度策略
    // You should specify a missingDimensionStrategy property for each
    // dimension that exists in a local dependency but not in your app.

翻译后:
您应该为每个属性指定一个丢失维度策略属性 ,那些存在于本地依赖项中但不存在于您的应用程序中的维度

存在于本地依赖关系中,但不存在于您的应用中
    missingDimensionStrategy 'abi', 'x86', 'arm64'
    }
    flavorDimensions 'tier'
    productFlavors {
        free {
            dimension 'tier'
            // You can override the default selection at the product flavor
            // level by configuring another missingDimensionStrategy property
            // for the "minApi" dimension.
翻译后:
您可以覆盖产品口味的默认选择,通过配置另一个missingDimensionStrategy属性进行级别 //用于“ minApi”维度
            missingDimensionStrategy 'minApi', 'minApi23', 'minApi18'
        }
        paid {}
    }
}


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容