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

Posted

技术标签:

【中文标题】Android 在代码中使用 Gradle Build 风格,例如 if 案例【英文标题】:Android using Gradle Build flavors in the code like an if case 【发布时间】:2014-07-29 22:49:09 【问题描述】:

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

基本上,admin 风格在主 Activity 上有一个额外的按钮。

我知道我可以为不同的风格定义不同的包/类。但是有没有办法根据风格制作一种 if case 来添加/删除一段代码?

基本上,我需要一个 Activity 的两个版本。但我不想要两个完全不同版本的活动并维护它们。

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

=> gradle 检查风味是否为 'admin'

=>如果是,添加这个按钮的代码

这可能吗?或者您是否需要两种不同的身体活动,从而在之后添加功能时同时维护它们。

【问题讨论】:

您可以在活动的 onCreate 上添加一行来执行此操作:检查风味并让按钮不可见(GONE) 那条线会是什么样子? if(!BuildConfig.FLAVOR.equals("admin")) buttonTheOneWeWanaHide.setVisibility(View.GONE); 【参考方案1】:

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

【讨论】:

注意:flavorDimension 在 Gradle 2.0 中已替换为 dimension @mixel 只是出于好奇,在这个实现中,我们需要将所有逻辑包含在一个构建中。如果需要简单地更改布尔值,任何人都可以反编译 apk 并重建?为什么不提取逻辑并将逻辑放在不同的文件夹中并使用souceSets 来决定要获取哪个文件夹?这样一来,将整个逻辑暴露给世界就没有问题了。 @IHC_Applroid 是的。 OP 说:“我知道我可以为不同的口味定义不同的包/类”,所以我认为他不能将代码放在不同的 sourceSets 中。 @IHC_Applroid 的想法是,如果我需要构建两个单独的活动,并且需要更改某些内容,我需要每次更改两次。这会降低应用程序的可维护性。因此我看起来像这样。虽然我同意你提到的潜在安全风险。但就我个人而言,我愿意承担这个风险。 最好以这种方式编码if ("admin".equals(BuildConfig.FLAVOR)),以防 BuildConfig 为空【参考方案2】:

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

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

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

那么你可以这样使用它:

if (BuildConfig.IS_ADMIN) 
    ...

【讨论】:

写的时候标有line-through,表示弃用。应该使用什么,以及如何使用? 我在 build.gradle 文件中保留了一些这样的字符串,但它并没有告诉我弃用。 @androiddeveloper 见***.com/questions/24119557/…(对已接受答案的第一条评论) @LoungeKatt 所以请改用“维度”。好的。 其余的应该仍然是最新的,但我只使用一个维度。在我的代码中使用BuildConfig.FLAVOR.equals 更容易。【参考方案3】:

您可以为每个风味定义不同的构建配置字段或不同的资源值(如字符串值),例如(根据Google's gradle tips and recipes),例如,

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

【讨论】:

【参考方案4】:

你可以试试这个方法

   productFlavors 
    def app_name = "you app name"
    development 
        versionCode 1
        versionName "1.0.1"          
        buildConfigField 'String', 'varibalename', ""           
    

    release 
        versionCode 1
        versionName "1.0.1"               
        buildConfigField 'String', 'varibalename', ""           
         

if(BuildConfig.varibalename)

【讨论】:

以上是关于Android 在代码中使用 Gradle Build 风格,例如 if 案例的主要内容,如果未能解决你的问题,请参考以下文章

Android Gradle 构建中不使用 libs 文件夹中的 Jar 文件

如何在 Android Studio 项目中将库添加到 Gradle 构建?

Android Gradle 插件自定义 Gradle 任务 ⑤ ( 为自定义 Gradle 任务添加依赖任务 | Gradle 任务依赖执行顺序控制 )

Android Gradle 插件自定义 Gradle 任务 ⑤ ( 为自定义 Gradle 任务添加依赖任务 | Gradle 任务依赖执行顺序控制 )

Android开发,使用Retrofit发送HTTP请求

开始使用gradle