问题 Android Gradle中每个风味的代码路径


我有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',解决方案就在此处


1959
2018-06-05 07:09


起源



答案:


@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"')
    }
}

你提出要做的问题是最后的定义 buildConfigField STRING, "URL_BASE" 每个人的价值观 buildType 将用于所有产品口味。所以你最终会得到的结果就像是 "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";

希望这可以帮助。


6
2018-06-10 11:39



我改变了我的代码,就像我更新的问题。我有不同的网址方案,所以我不能以同样的方式应用你的答案,我必须调整它,你可以看到。 - beni


答案:


@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"')
    }
}

你提出要做的问题是最后的定义 buildConfigField STRING, "URL_BASE" 每个人的价值观 buildType 将用于所有产品口味。所以你最终会得到的结果就像是 "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";

希望这可以帮助。


6
2018-06-10 11:39



我改变了我的代码,就像我更新的问题。我有不同的网址方案,所以我不能以同样的方式应用你的答案,我必须调整它,你可以看到。 - beni


构建类型不是产品风味的一部分,反之亦然。 Variant基于构建类型和产品风格计算。使用此方法,您可以使用产品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}\"")
}

5
2018-06-17 01:40



我们必须明确地调用“project.android.applicationVariants.all”。 - Tushar Pandey
可能还有其他方式,但我不知道。没有声明的做法,这是你感兴趣的。 - n4h0y


我不知道如何为多个BuildVariants(构建类型+风格)设置不同的值 build.gradle 随着 buildConfigField 方法。

但是,您可以使用不同的值 url_base 内 res/values/strings.xml

就像是:

<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


2
2018-06-05 13:16



那些与每种构建类型相等的java类呢?我是否必须克隆每个java类以添加到product1Debug,product1Release中?或者我是否必须创建一个名为product1的文件夹,这个代码在其中?例如,一个名为SplashActivity.java的java类与product1中的构建类型debug和release相同。谢谢 - beni
对于java类,您必须为每个buildTypes放置1个类。你可以在这种情况下使用: - app/src/debug:  - app/src/product1Release  - app/src/product2Release - Gabriele Mariotti


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

1
2018-06-10 17:19