Android在代码中使用Gradle Build风格,例如if情况


77

我正在尝试构建风味。在我的build.gradle中,我定义了2种口味,一种是普通口味,另一种是管理员口味。

基本上,管理员风格在主要活动上有一个额外的按钮。

我知道我可以为不同的口味定义不同的包/类。但是,是否有一种方法可以根据口味来添加/删除一段代码呢?

基本上,我将需要一个Activity的两个版本。但我不希望该活动的两个完全不同的版本来维护它们。

所以在我的活动中,我想做

=> gradle检查风味是否为“ admin”

=>如果是,请添加此按钮的代码

这可能吗?还是您需要两种不同的身体活动,并在以后添加功能时同时维护它们。


您可以在活动的onCreate上仅添加一行以执行以下操作:检查风味并使按钮不可见(消失)
Selvin

那条线看起来怎么样?
Stephan Celis 2014年

4
if(!BuildConfig.FLAVOR.equals("admin")) { buttonTheOneWeWanaHide.setVisibility(View.GONE);}
Selvin 2014年

Answers:


130

BuildConfig.FLAVOR给您结合的产品风味。因此,如果您只有一个口味维度:

productFlavors {
    normal {
    }

    admin {
    }
}

然后,您可以检查一下:

if (BuildConfig.FLAVOR.equals("admin")) {
    ...
}

但是,如果您有多个口味维度:

flavorDimensions "access", "color"

productFlavors {
    normal {
        dimension "access"
    }

    admin {
        dimension "access"
    }

    red {
        dimension "color"
    }

    blue {
        dimension "color"
    }
}

也有BuildConfig.FLAVOR_accessBuildConfig.FLAVOR_color字段,因此您应该像这样检查它:

if (BuildConfig.FLAVOR_access.equals("admin")) {
    ...
}

BuildConfig.FLAVOR包含完整的风味名称。例如,adminBlue


注意:在Gradle 2.0中flavorDimension已被替换dimension
dermatthias

1
@mixel出于好奇,在此实现中,我们需要将ALL逻辑包含在一个构建中。任何人都可以反编译apk并根据需要重新构建以简单地更改布尔值?为什么不提取逻辑并将逻辑放置在不同的文件夹中并souceSets用来确定要提取的文件夹?这样,将整个逻辑暴露给世界就没有问题了。
IHC_Applroid

@IHC_Applroid是的。OP说:“我知道我可以为不同的口味定义不同的包/类”,所以我认为他不能选择将代码放在不同的中sourceSets
mixel

@IHC_Applroid的想法是,如果我需要构建两个单独的活动,并且需要进行某些更改,则需要每次对其进行两次更改。这将降低应用程序的可维护性。因此,我一直在寻找这样的东西。尽管我同意您提到的潜在安全风险。但就我个人而言,我愿意冒险。
斯蒂芬·塞利斯

最好以这种方式编写代码if ("admin".equals(BuildConfig.FLAVOR)),以防BuildConfig为空
chrizonline

76

为避免条件中出现纯字符串,可以定义一个布尔属性:

productFlavors {
    normal {
        flavorDimension "access"
        buildConfigField 'boolean', 'IS_ADMIN', 'false'
    }

    admin {
        flavorDimension "access"
        buildConfigField 'boolean', 'IS_ADMIN', 'true'
    }
}

然后,您可以像这样使用它:

if (BuildConfig.IS_ADMIN) {
    ...
}

编写时,它会标有直通标记,即弃用标记。应该使用什么代替,如何使用?
Android开发人员

我在build.gradle文件中保留了一些这样的字符串,但是它并没有告诉我弃用。
Madhan '18

@androiddeveloper参见stackoverflow.com/questions/24119557/…(对已接受答案的第一条评论)
被遗弃的购物车

@LoungeKatt因此,请改用“维度”。好。
Android开发人员

其余的应该仍然是最新的,但是我只使用一个维度。BuildConfig.FLAVOR.equals在我的代码中坚持比较容易。
被遗弃的购物车

0

您可以为每种口味定义不同的构建配置字段或不同的资源值(例如字符串值),例如(根据Google的gradle技巧和食谱),例如

android {
  ...
  buildTypes {
    release {
      // These values are defined only for the release build, which
      // is typically used for full builds and continuous builds.
      buildConfigField("String", "BUILD_TIME", "\"${minutesSinceEpoch}\"")
      resValue("string", "build_time", "${minutesSinceEpoch}")
      ...
    }
    debug {
      // Use static values for incremental builds to ensure that
      // resource files and BuildConfig aren't rebuilt with each run.
      // If they were dynamic, they would prevent certain benefits of
      // Instant Run as well as Gradle UP-TO-DATE checks.
      buildConfigField("String", "BUILD_TIME", "\"0\"")
      resValue("string", "build_time", "0")
    }
  }
}

所以在这种情况下

productFlavors {
    normal {
        dimension "access"
        buildConfigField("boolean", "IS_ADMIN", "false")
    }

    admin {
        dimension "access"
        buildConfigField("boolean", "IS_ADMIN", "true")
    }
}

然后像

if (BuildConfig.IS_ADMIN) {
    ...
} else {
    ...
}

或者只是针对不同的口味使用不同的字符串值,则可以使用不同的字符串来完成操作,resValues那么您甚至不需要if/then

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.