Android Studio / Gradle中的productFlavor变量

时间:2018-03-06 13:36:19

标签: android gradle

我有一个具有以下产品风格的Android应用程序:

productFlavors {
    local {

    }

    development {


    }

    production {

    }
}

然后在build.grade

的底部有以下内容:
File crashlyticsProperties = new File("${project.projectDir.absolutePath}/fabric.properties")
android.applicationVariants.all { variant ->
    def variantSuffix = variant.name.capitalize()
    def generateResourcesTask = project.tasks.getByName("fabricGenerateResources${variantSuffix}")
    def generatePropertiesTask = task("fabricGenerateProperties${variantSuffix}") << {
        Properties properties = new Properties()
        properties.put("apiSecret", WHAT_GOES_HERE)
        properties.put("apiKey", WHAT_GOES_HERE)
        PropertiesUtils.injectPropertyInFile(crashlyticsProperties, properties, "")
    }
    generateResourcesTask.dependsOn generatePropertiesTask
}

我正在尝试为api secret/key设置crashlytics,但我需要根据我正在构建的产品风格来设置这些。

properties.put("apiSecret", WHAT_GOES_HERE)
properties.put("apiKey", WHAT_GOES_HERE)

如何设置/获取这些变量?

更新#1

我已将以下内容添加到build.gradle

productFlavors {
    local {
        buildConfigField "String", "CRASHLYTICS_API_SECRET", "1234"
        buildConfigField "String", "CRASHLYTICS_API_KEY", "1234"
    }

    development {
        buildConfigField "String", "CRASHLYTICS_API_SECRET", "1234"
        buildConfigField "String", "CRASHLYTICS_API_KEY", "1234"
    }

    production {
        buildConfigField "String", "CRASHLYTICS_API_SECRET", "1234"
        buildConfigField "String", "CRASHLYTICS_API_KEY", "1234"
    }
}

然后在我build.gradle文件的底部:

File crashlyticsProperties = new File("${project.projectDir.absolutePath}/fabric.properties")
android.applicationVariants.all { variant ->
    def variantSuffix = variant.name.capitalize()
    def generateResourcesTask = project.tasks.getByName("fabricGenerateResources${variantSuffix}")
    def generatePropertiesTask = task("fabricGenerateProperties${variantSuffix}") << {
        Properties properties = new Properties()
        println "...copying apiSecret for ${variant.name}"
        properties.put("apiSecret", BuildConfig.CRASHLYTICS_API_SECRET)
        println "...copying apiKey for ${variant.name}"
        properties.put("apiKey", BuildConfig.CRASHLYTICS_API_KEY)
        PropertiesUtils.injectPropertyInFile(crashlyticsProperties, properties, "")
    }
    generateResourcesTask.dependsOn generatePropertiesTask
}

然而,这不会编译并给我:

  

错误:(334,1)任务':app:fabricGeneratePropertiesDevelopmentDebug'的执行失败。   无法在任务':app:fabricGeneratePropertiesDevelopmentDebug'上找到属性'BuildConfig'。

4 个答案:

答案 0 :(得分:2)

对于此错误:

  

错误:(334,1)任务':app:fabricGeneratePropertiesDevelopmentDebug'的执行失败。无法在任务':app:fabricGeneratePropertiesDevelopmentDebug'上找到属性'BuildConfig'。

使用不同的结构,例如:

variant.mergedFlavor.buildConfigFields["CRASHLYTICS_API_SECRET"].value

当然这个解决方案期望定义这样的BuildConfig字段。 如果您希望字段不存在,请务必先检查是否存在。

编辑:

如果您想要问题中描述的解决方案:

File crashlyticsProperties = new File("${project.projectDir.absolutePath}/fabric.properties")
android.applicationVariants.all { variant ->
    def variantSuffix = variant.name.capitalize()
    def generateResourcesTask = project.tasks.getByName("fabricGenerateResources${variantSuffix}")
    def generatePropertiesTask = task("fabricGenerateProperties${variantSuffix}") << {
        Properties properties = new Properties()
        println "...copying apiSecret for ${variant.name}"
        properties.put("apiSecret", variant.mergedFlavor.buildConfigFields.get("CRASHLYTICS_API_SECRET").value)
        println "...copying apiKey for ${variant.name}"
        properties.put("apiKey", variant.mergedFlavor.buildConfigFields.get("CRASHLYTICS_API_KEY").value)
        PropertiesUtils.injectPropertyInFile(crashlyticsProperties, properties, "")
    }
    generateResourcesTask.dependsOn generatePropertiesTask
}

答案 1 :(得分:1)

你可以为每种味道设置不同的buildConfigFields,你可以轻松地声明多个字符串变量并为每种味道分开键

喜欢:

local { buildConfigField "String", "KEY", '"abcKey' } 
development { buildConfigField "String", "KEY", '"xyzKey' } 

并在java文件中使用这些变量,如下所示

properties.put("apiSecret", BuildConfig.KEY)

答案 2 :(得分:1)

易:

applicationVariants.all { variant ->
    variant.outputs.all { output -> 
        def flavor = variant.productFlavors[0].name.capitalize()

        if (flavor == "Local") {
             buildConfigField "string", "CRASHLYTICS_API_SECRET", "1234"
             buildConfigField "string", "CRASHLYTICS_API_KEY", "5678"
        }

        if (flavor == "Development") {
             buildConfigField "string", "CRASHLYTICS_API_SECRET", "1234"
             buildConfigField "string", "CRASHLYTICS_API_KEY", "5678"
        }

        if (flavor == "Production") {
            buildConfigField "string", "CRASHLYTICS_API_SECRET", "1234"
            buildConfigField "string", "CRASHLYTICS_API_KEY", "5678"
        }
    }
}

将其放在productFlavors块下。您可以稍后在代码中使用BuildConfig.CRASHLYTICS_API_SECRET

答案 3 :(得分:0)

您收到该错误的原因是BuildConfig是Java类,而不是Gradle类。 BuildConfig只能在其他Java类中使用。

然而,根据Gradle风格,有一种更简单的方法来获取具有不同内容的文件。

考虑通常的项目结构:

/app
    /src
        /main
            /java
            /res
            /assets
            ...

如果您希望每个Gradle flavor使用不同的“fabric.properties”文件,则可以为/ src下的每个Gradle风格创建一个文件夹(文件夹名称必须与Gradle风味名称相同)并将文件保存在其中,如下所示:

/app
    /src
       /main
            /java
            /res
            /assets
            ...
       /local
           /fabric.properties
       /development
           /fabric.properties
       /production
           /fabric.properties

无需更改任何内容或编写任何Gradle脚本即可运行。

有关源集的更多详细信息,请阅读https://developer.android.com/studio/build/build-variants.html#sourcesets