使一个产品口味成为另一个产品口味的子类

17

我正在设置我的应用程序中的产品口味,遇到一个问题。我的两个产品口味非常相似,只有少量资源不同,我们称它们为 FlavorA 和 FlavorB。我想设置 FlavorA 为 FlavorB 的父级,这样 FlavorB 就可以覆盖 FlavorA 中的一些资源,然后 FlavorA 又可以覆盖 main 中的很多资源。是否有一种可以建立这样的口味层次结构的方法?目前,我需要在两个品种之间复制大量的资源才能使它工作,我想消除这种重复。

编辑:好的,我已经收到了一些回答(都被删除了),与我的问题无关,所以让我澄清一下。这与 Java 面向对象编程没有关系,我已经对此非常熟悉了。:)

我遇到的问题是,我有一个免费/付费版本的应用,还有几个只包含主题更改的白标签。付费版仅从免费版更改了少量资产(除代码更改外)。这是我的productFlavors的样子:

productFlavors {
        whiteLabelA {
            applicationId "com.whiteLabelA.android"
        }

        whiteLabelB {
            applicationId "com.whiteLabelB.android"
        }

        mainFree {
            applicationId "com.mainFree.android"
        }

        mainPaid {
            applicationId "com.mainFree.android.paid"
        }
    }

我希望mainPaid覆盖mainFree,因为它只更改了一些资源。我希望这样做而不是使用免费/付费的构建类型,因为白标没有付费版本,并且采用分层架构会更容易,如下所示:

mainPaid extends mainFree {
    applicationId "com.mainFree.android.paid"
}

@travor-e,你有没有找到这个问题的答案? - Sean Barbeau
1
@SeanBarbeau 有点像。目前还没有答案表明是否可以扩展flavors。我通过一种不需要扩展flavors的方式解决了我的问题,所以我保留了这个问题。顺便说一下,我通过将mainFree flavor资源放在主资源文件夹中来解决我的问题,因为我意识到这应该是默认构建的。 - telkins
3
构建类型具有initWith命令,允许复制gradle配置块(尽管依赖的构建类型仍需要自己的源集),但据我所知,口味没有相应的等价物。 - stkent
这里有一个链接,提供一些提示来实现这种行为。我需要完全相同的效果,但直到现在都没有找到解决方案:https://groups.google.com/forum/?hl=fr#!topic/adt-dev/f2I9LQIogOM - Tobliug
3个回答

11
我发现了两种解决方案: 1. 使用口味维度(flavor dimensions)
android {
  ...
  flavorDimensions 'palette', 'color'

  productFlavors {
    blackAndWhite {
      dimension 'palette'
    }
    redAndWhite {
      dimension 'palette'
    }
    red {
      dimension 'color'
    }
    white {
      dimension 'color'
    }
  }
  variantFilter { variant ->
    def first = variant.getFlavors().get(0).name
    def second = variant.getFlavors().get(1).name
    if(!(first.equals('blackAndWhite') && second.equals('white')) ||
       !(first.equals('redAndWhite') && (second.equals('white') || second.equals('red')))) {
       variant.setIgnore(true);
    }
  }
  ...
}

由于variantFilter的存在,我们只有3种组合而不是4种:
blackAndWhite => white

redAndWhite   => white
              => red

你可以将其视为红色扩展红白色白色扩展黑白色红白色

这个答案和变体过滤器文档很有帮助。

2. 编辑源集。

productFlavors{
    flavor1 {
    }
    flavor2 {
    }
}

sourceSets {
    flavor2 {
        java.srcDirs = sourceSets.flavor1.java.srcDirs
        res.srcDirs = sourceSets.flavor1.res.srcDirs
        resources.srcDirs = sourceSets.flavor1.resources.srcDirs
        aidl.srcDirs = sourceSets.flavor1.aidl.srcDirs
        renderscript.srcDirs = sourceSets.flavor1.renderscript.srcDirs
        assets.srcDirs = sourceSets.flavor1.assets.srcDirs
    }
}

这个代码示例是毫不掩饰地从这篇博客文章中复制的。非常感谢作者。


好的答案展示了如何处理代码继承,但是要处理依赖项的继承,请参见我在这里的答案:https://dev59.com/DqTia4cB1Zd3GeqP9iyK#54745210 - Jonathan Ellis

3

我在寻找gradle中类似的东西,并发现多口味变体。我有一个应用程序应该有版本A和B,每个版本都有开发和专业环境,所以我最终在我的gradle中得到了这个:

flavorDimensions 'app', 'environment'

productFlavors {
    versionA {
        flavorDimension 'app'
    }
    versionB {
        flavorDimension 'app'
    }
    pre {
        flavorDimension 'environment'
    }
    pro {
        flavorDimension 'environment'
    }
}

在我的构建变体中,我有versionAPreDebug、versionAPreRelease、versionBPreDebug、versionBPreRelease等版本。我认为你需要的是类似这样的东西。


在产品口味块内,只需使用 dimension 而不是 flavorDimension - Rémi Latapy

2

我认为你不能直接在android对象中完成这个操作,但是你可以使用配置函数在一个flavor上设置公共属性。将此放置在android对象之后:

void configureWhiteLabelFlavor(flavor) {
    flavor.useJack = true
}

configureWhiteLabelFlavor(android.productFlavors.whiteLabelA)

如果需要,您可以通过从此函数调用其他函数来实现深度继承。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接