产品味道是另一个孩子的孩子

时间:2014-07-29 18:15:59

标签: android gradle

我在我的应用中设置了产品口味并遇到了一个问题。我的两种产品口味彼此非常相似,只是有一些资源不同,我们称之为FlavorA和FlavorB。我想设置它以使FlavorA成为FlavorB的父级,这样FlavorB可以覆盖FlavorA的一些资源,然后FlavorA覆盖来自main的一堆资源。有没有办法设置这样的风味层次结构?现在我需要在两者之间复制大量资源才能使它工作,我想消除这种重复。

编辑:好的。到目前为止,我有几个答案(都已删除)与我的问题无关,所以让我澄清一下。这与Java OOP没有关系,我已经很清楚了。 :)

我遇到的问题是我的应用程序的免费/付费版本,以及几个仅包含主题更改的白色标签。付费版本仅更改免费版本中的一些资产(除了代码更改)。这就是我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"
}

3 个答案:

答案 0 :(得分:6)

我找到了两个解决方案:

<强> 1。使用风味尺寸。

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

您可以将其视为red延长redAndWhitewhite延长blackAndWhiteredAndWhite

This answer和变体过滤器documentation很有帮助。

<强> 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
    }
}

代码示例是从this blog post无耻地复制的。非常感谢它的作者。

答案 1 :(得分:3)

我在gradle中寻找类似的东西并找到了Multi-flavor variants。我有一个应该有A和B版本的应用程序,每个版本都有dev和pro环境,所以我最终得到了这个:#/ p>

flavorDimensions 'app', 'environment'

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

在我的构建变体中,我有versionAPreDebug,versionAPreRelease,versionBPreDebug,versionBPreRelease等。我认为你需要的是这样的。

答案 2 :(得分:2)

我认为您无法直接在android对象中执行此操作,但您可以使用配置函数在flavor上设置公共属性。把它放在android对象之后:

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

configureWhiteLabelFlavor(android.productFlavors.whiteLabelA)

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

相关问题