Gradle Android插件-如何添加自定义flavor属性?

20

在Gradle的Android插件中,是否有一种方法可以向productFlavor或buildType添加自定义属性?我希望在构建变体的配置中具有这种额外的灵活性,以便在为构建变体指定任务时可以检查我的自定义属性。

productFlavors {
    flavorGroups "drm", "storeType"
    googlePlay {
        flavorGroup "storeType"
        buildConfig "public static final String TARGET_STORE = \"google\";"
    }
    samsungApps {
        flavorGroup "storeType"
        buildConfig "public static final String TARGET_STORE = \"samsung\";"
    }

    platformDrm {
        flavorGroup "drm"
    }

    widevineAppDrm {
        flavorGroup "drm"
        minSdkVersion 9
        useWidevineAppDrmLib true
    }

所以在这里,您可以看到我已经向构建变体添加了自定义属性"useWidevineAppDrmLib"。 希望能够在buildVariant.mergedFlavor中看到相同的属性,以便我可以检查该属性值并执行其他构建任务,例如在将属性设置为true时打包额外的.so文件:

android.applicationVariants.each { variant -> if(variant.mergedFlavor.useWidevineAppDrmLib ) { ... // 添加复制 .so 的任务 } }

也许已经有一种方法可以做到这一点,但我还没有找到...... 对于我来说,检查构建变体名称是否包含子字符串(flavor名称)是有效的,但看起来很杂乱。

理想情况下,我希望拥有不同类型自定义属性的构建类型和产品风味映射。

2个回答

21
您可以通过扩展对象来动态添加属性。 因此,当添加flavor对象时,您可以使用类似以下代码的方式进行操作:
// First declare a class that holds a boolean
class BooleanExtension {
  boolean value
  BooleanExtension(boolean value) {
    this.value = value
  }

  public void setValue(boolean value) {
    this.value = value
  }

  public boolean getValue() {
    return value
  }
}

android {
  // add the boolean extension to all flavor object when they are created.
  productFlavors.whenObjectAdded { flavor ->
    flavor.extensions.create("useWidevineAppDrmLib", BooleanExtension, false)
  }

  // then we can set the value on the extension of any flavor object
  productFlavors {
    widevineAppDrm {
      useWidevineAppDrmLib.value true
    }
  }
}

但是这个不会传递到合并的 flavor。因此你需要执行以下操作:

android.applicationVariants.each { variant ->
  if (variant.productFlavors.get(0).useWidevineAppDrmLib.value) {
    ...
  }
}

根据 @blackdigger 的反馈进行编辑,使代码真正可用。


1
我是这样做的:在“android”部分上面定义扩展类 - 否则会出现编译错误: class BooleanExtension { Boolean value BooleanExtension(Boolean value) { this.value = value } public void setValue(Boolean value) { this.value = value } public Boolean getValue() { return value } } 然后写: widevineAppDrm { ... useWidevineAppDrmLib.value true ... } ....和: if (variant.productFlavors.get(0).useWidevineAppDrmLib.value) {...} - blackdigger
1
还有一件事,为了添加口味扩展,我必须执行以下操作: productFlavors.whenObjectAdded { flavor -> flavor.extensions.create("useWidevineAppDrmLib", BooleanExtension, false) } - blackdigger
1
你可能希望让你的BooleanExtension使用boolean而不是Boolean。 - Xavier Ducrohet
@XavierDucrohet 谢谢您提供这个有用的答案!我想知道:是否有关于产品风味的API文档?因为我很想看看flavor.extensions.create方法的文档,以便弄清楚末尾的“false”是什么意思:)。因为我正在创建一个StringProperty,所以我想弄清楚那个“false”是BooleanProperty的默认值还是其他什么东西。 - AgentKnopf
@XavierDucrohet 我对最后一段代码的目的也不是很清楚: android.applicationVariants.each { variant -> if (variant.productFlavors.get(0).useWidevineAppDrmLib.value) { ... } }你应该在if语句中做些什么呢?productFlavors.get(0)返回的是googlePlay产品口味吗?或者说哪几个口味被存储在productFlavors属性/对象中? - AgentKnopf

17

有一种替代方案,不需要创建自己的自定义类。您可以利用已经存在的extras属性,这个属性已经附加到了“productFlavors”类上。这个属性的设计目的就是允许用户自定义变量。

android {
  // We can add any custom variable so long as it's prefaced with ext
  productFlavors {
    widevineAppDrm {
      ext.useWidevineAppDrmLib = true
    }
  }
}

然后您可以像这样稍后引用。请注意,如果您没有将自定义变量添加到其他productFlavors中,则需要确保首先检查它,否则Gradle将抱怨找不到该属性。

android.applicationVariants.each { variant ->
    if (variant.productFlavors[0].ext.has("useWidevineAppDrmLib")) {
        if (variant.productFlavors.get(0).ext.useWidevineAppDrmLib) {
            ...
        }
    }
}

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