【问题标题】:Code Path per Flavor in Android GradleAndroid Gradle 中每种风格的代码路径
【发布时间】:2016-10-08 18:04:32
【问题描述】:

我有 2 个 buildTypes(调试、发布)和 2 个 productFlavors(product1、product2)。我想为每个 buildType 和 productFlavors 定义一个 buildConfigField。 buildConfigField 是应用程序从服务器下载数据的 url,它会根据 productFlavor 和 buildTypes 变化。

现在,我有:

buildTypes {
    debug {
        debuggable true
    }
    release {
        debuggable false
    }
}
productFlavors {
    product1 {
        buildConfigField STRING, "URL_BASE",  '"https://api1.release.com"'

    }
    product2 {
        buildConfigField STRING, "URL_BASE", '"https://api2.release.com"'

    }
}

但我想要这样的东西:

buildTypes {
    debug {
        debuggable true
    }
    release {
        debuggable false
    }
}
productFlavors {
    product1 {
        debug {
            buildConfigField STRING, "URL_BASE",  '"https://api1.debug.com"'
        }
        release {
            buildConfigField STRING, "URL_BASE",  '"https://api1.release.com"'
    }
    product2 {
        debug {
            buildConfigField STRING, "URL_BASE", '"https://api2.debug.com"'
            }
        release {
            buildConfigField STRING, "URL_BASE", '"https://api2.release.com"'
        }
    }
}

我怎样才能做到这一点?

更新:

每个 URL_BASE 都有不同的模式,因此我无法对 URL 进行分组。一种可行的解决方案是在不同的构建类型中添加 2 种风味的 url 基础,并在风味中选择正确的一种。

buildTypes {
    debug {
        debuggable true
        buildConfigField STRING, API_VARIANT_PRODUCT1, '"api1.deb.com"'
        buildConfigField STRING, API_VARIANT_PRODUCT2, '"api2.debug.com"'

    }
    release {
        debuggable false
        buildConfigField STRING, API_VARIANT_PRODUCT1, '"api1.release.com"'
        buildConfigField STRING, API_VARIANT_PRODUCT2, '"api2.release.com"'
    }
}

productFlavors {
    product1 {
        buildConfigField STRING, URL_BASE, '"https://" + API_VARIANT_PRODUCT1 + "/v1"'
    }
    product2 {
        buildConfigField STRING, URL_BASE, '"https://" + API_VARIANT_PRODUCT2 + "/v1"'
    }
  }
}

更新 2

如果您需要在 gradle 中添加资源,例如“KEY_MAP”,解决方案在 page 中。

【问题讨论】:

    标签: android gradle android-gradle-plugin build.gradle


    【解决方案1】:

    Build Type 不是 Product Flavor 的一部分,反之亦然。变体是根据构建类型和产品风味计算的。使用它,您可以使用产品风格和构建类型创建具有一致格式的扩展(选项 1)或属性(选项 2)。

    选项 1

    ext.product1_release_base_url = 'http://baseurl.myproduct/public'
    ext.product2_release_base_url = 'http://baseurl.yourproduct/secure'
    ext.product1_debug_base_url = 'http://debugurl.myproduct/test'
    ext.product2_debug_base_url = 'http://yourproduct/debug'
    
    android {
        buildTypes {
            release {
                minifyEnabled true
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
            debug {
                minifyEnabled false
            }
        }
        productFlavors {
            product1 {}
            product2 {}
        }
    }
    
    project.android.applicationVariants.all {variant ->
        def url = project.ext."${variant.flavorName}_${variant.buildType.name}_base_url"
        variant.buildConfigField('String', 'URL_BASE', "\"${url}\"")
    }
    

    选项 2

    在 gradle.properties 中

    product1_release_base_url = 'http://baseurl.myproduct/public'
    product2_release_base_url = 'http://baseurl.yourproduct/secure'
    product1_debug_base_url = 'http://debugurl.myproduct/test'
    product2_debug_base_url = 'http://yourproduct/debug'
    

    在 build.gradle 中

    android {
        buildTypes {
            release {}
            debug {}
        }
        productFlavors {
            product1 {}
            product2 {}
        }
    }
    
    project.android.applicationVariants.all {variant ->
        def url = project."${variant.flavorName}_${variant.buildType.name}_base_url"
        variant.buildConfigField('String', 'URL_BASE', "\"${url}\"")
    }
    

    【讨论】:

    • 我们是否必须明确调用“project.android.applicationVariants.all”。
    • 可能还有其他方法,但我不知道。没有您感兴趣的声明方式。
    • 你能告诉我为什么是 "\"${url}\"" 而不是 ${url} 直接吗?
    • 对于选项 2,您必须提供不带简单引号的 url:product1_release_base_url = http://baseurl.myproduct/public
    • @n4h0y 如何避免不存在的额外道具?比如你不小心添加了新口味product3,如何忽略这个并继续循环?
    【解决方案2】:

    @Beni,你可以用这样的东西

    buildTypes {
        debug {
            debuggable true
            buildConfigField("String", "API_VARIANT", '"debugvariant"')
        }
        release {
            debuggable false
            buildConfigField("String", "API_VARIANT", '"releasevariant"')
        }
    }
    productFlavors {
        product1 {
            buildConfigField("String", "URL_BASE", '"https://api1." + API_VARIANT + ".com"')
        }
        product2 {
            buildConfigField("String", "URL_BASE", '"https://api2." + API_VARIANT + ".com"')
        }
    }
    

    您提议做的问题是每个buildTypebuildConfigField STRING, "URL_BASE" 值的最后定义将在所有产品风格中使用。所以你最终会得到类似"https://api2.release.com" 的两个版本。

    使用上述方法,您最终会在每个变体的 BuildConfig 文件中得到类似的内容

    // Fields from build type: debug
    public static final String API_VARIANT = ["debugvariant"|"releasevariant"];
    // Fields from product flavor: [product1|product2]
    public static final String URL_BASE = "https://[api1|api2]." + API_VARIANT + ".com";
    

    希望这会有所帮助。

    【讨论】:

    • 我像更新的问题一样更改了我的代码。我有不同的 url 方案,所以我不能以同样的方式应用你的答案,我必须调整它,如你所见。
    【解决方案3】:

    我不知道如何使用buildConfigField 方法在build.gradle 中为多个BuildVariants(构建类型+风味)设置不同的值。

    但是,您可以在 res/values/strings.xml 中为 url_base 使用不同的值。

    类似:

    <string name="url_base">https://api1.debug.com</string>
    

    然后你可以在这些文件夹中创建相同的字符串资源:

     - app/src/product1Debug: Contains product1-debug-related code/resources
     - app/src/product1Release: Contains product1-release-related code/resources
     - app/src/product2Debug: Contains product2-debug-related code/resources
     - app/src/product2Release: Contains product2-release-related code/resources
    

    当然,在BuildConfig 内有一个值是不一样的,并且不如build.gradle 的配置那么舒服。

    【讨论】:

    • 对于每种构建类型都相等的 java 类呢?我是否必须克隆每个 java 类才能添加到 product1Debug、product1Release 中?还是我必须创建一个名为 product1 的文件夹,并且此代码在其中?例如,一个名为 SplashActivity.java 的 java 类与 product1 中的构建类型 debug 和 release 相同。谢谢
    • 对于 java 类,您必须为每个 buildTypes 放置 1 个类。在这种情况下你可以使用:- app/src/debug:- app/src/product1Release- app/src/product2Release
    【解决方案4】:
    applicationVariants.all { variant ->
    
       def apiVariant = variant.getFlavorName == "product1" ? "api1" : "api2"
       def server = variant.buildType.name == "debug" ? "debug" : "release"
    
       variant.buildConfigField STRING, URL_BASE, "http://" + apiVariant + "." + server + ".com"
    }
    

    【讨论】:

      猜你喜欢
      • 2015-02-15
      • 1970-01-01
      • 1970-01-01
      • 2014-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-16
      相关资源
      最近更新 更多