简体   繁体   English

如何在 Android Gradle 配置中获取当前的 buildType

[英]How to get current buildType in Android Gradle configuration

I want to dynamically add a dependency in an Android Gradle project based on the current buildType.我想根据当前的 buildType 在 Android Gradle 项目中动态添加依赖项。 I know I can specify the buildType in the dependency :我知道我可以在依赖项中指定 buildType

compile project(path: ':lib1', configuration: 'debug')

But how can I use the current buildType to specify which variant of the library I want to import, so that a debug or release build automatically imports the debug or release variant of the library?但是如何使用当前的 buildType 来指定我要导入的库的哪个变体,以便调试或发布版本自动导入库的调试或发布变体? What I want is something like this (where currentBuildType is a variable containing the name of the currently used buildType):我想要的是这样的(其中 currentBuildType 是一个包含当前使用的 buildType 名称的变量):

compile project(path: ':lib1', configuration: currentBuildType)

The library project I want to import has set publishNonDefault true , so all buildTypes are published.我要导入的库项目已设置publishNonDefault true ,因此所有 buildType 都已发布。

You can use您可以使用

if (gradle.startParameter.taskNames.contains("assembleExample")) {
    // do stuff
}

That variable will be set before the buildConfig block is evaluated该变量将在评估buildConfig块之前设置

I could not find a clean way to get the current build type during the configuration phase of Gradle.在 Gradle 的配置阶段,我找不到一种干净的方法来获取当前的构建类型。 Instead I define the dependency for each build type separately like that:相反,我分别为每个构建类型定义了依赖关系,如下所示:

debugCompile project(path: ':lib1', configuration: 'debug')
releaseCompile project(path: ':lib1', configuration: 'release')

If you have many build types and many project dependencies this can get very verbose, but it is possible to add a function to make the dependency a one-liner.如果您有许多构建类型和许多项目依赖项,这可能会变得非常冗长,但是可以添加一个函数使依赖项成为单行依赖项。 You need to add this to your main Gradle build file:您需要将其添加到您的主要 Gradle 构建文件中:

subprojects {
    android {
        dependencies.metaClass.allCompile { dependency ->
            buildTypes.each { buildType ->
                "${buildType.name}Compile" project(path: ":${dependency.name}", configuration: buildType.name)
            }
        }
    }
}

Then you can add project dependencies in your Gradle modules like this:然后你可以像这样在你的 Gradle 模块中添加项目依赖项:

allCompile project(':lib1')

If you also use build flavors you would have to adapt the solution.如果您还使用构建风格,则必须调整解决方案。 See this link for a documentation of the feature: http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Library-Publication有关该功能的文档,请参阅此链接: http : //tools.android.com/tech-docs/new-build-system/user-guide#TOC-Library-Publication

Please note that the Android team is working on an improvement for this behaviour: https://code.google.com/p/android/issues/detail?id=52962请注意,Android 团队正在改进此行为: https : //code.google.com/p/android/issues/detail?id=52962

Add a task which depends on each assembleXxx task and property setting up after it invoked添加一个任务,它依赖于每个 assembleXxx 任务和它调用后的属性设置

ext {
    currentConfig = ""
}
task generateConfigProperty(dependsOn: 'installDebug') {

    android.applicationVariants.all { variant ->
        variant.outputs.each { output ->

            def taskName = "taskindicate$output.name"
            task "$taskName"() << {
                project.ext.set("currentConfig", "$output.name")
            }
            output.assemble.dependsOn "taskindicate$output.name"
        }
    }

}

task getConfig(dependsOn: ['installDebug', 'generateConfigProperty']) << {
    println("My config is $currentConfig")
}

took idea from the answer答案中汲取灵感

This one is quite simple:这个很简单:

android {
    applicationVariants.all { variant ->
        variant.buildType.name // this is the value!
    }
}

Edit: Apparently at some point with gradle update, this is not working as I mentioned in a comment below.编辑:显然在某些时候使用 gradle 更新,这不起作用,正如我在下面的评论中提到的那样。 So I'd recommend checking other options.所以我建议检查其他选项。

This is the easiest way to get the result you want. 这是获得所需结果的最简单方法。 You define the global variable, then updated it for use later where ever needed. 您可以定义全局变量,然后更新它以便以后需要时使用。

// query git for the SHA, Tag and commit count. Use these to automate versioning.
def gitSha = 'git rev-parse --short HEAD'.execute([], project.rootDir).text.trim()
//def gitTag = 'git describe --tags'.execute([], project.rootDir).text.trim()
def gitCommitCount = 100 +
        Integer.parseInt('git rev-list --count HEAD'.execute([], project.rootDir).text.trim())
def buildTime = new Date().format("yyyy-MM-dd'T'HH:mm'Z'", TimeZone.getTimeZone("UTC"))

def versionMajor = 1
def versionMinor = 5
def versionPatch = 2
def versionBuild = 0 // bump for dogfood builds, public betas, etc.

def buildType // define here to update in loop

android {

    applicationVariants.all { variant ->
        buildType = variant.buildType.name // sets the current build type
    }

    defaultConfig {
        applicationId "com.example"
        minSdkVersion 19
        targetSdkVersion 25
        vectorDrawables.useSupportLibrary = true

        versionCode gitCommitCount
        versionName "${versionMajor}.${versionMinor}.${versionPatch}.${versionBuild}"
        versionNameSuffix "-${buildType}-build-${buildTime}"

}
// declare a custom task class so you can reuse it for the different
// variants
class MyTask extends DefaultTask {
     String mVariantName;
     public void setVariantName(String variant) {mVariantName = variant;}
     public String getVariantName() { return mVariantName; }
     @TaskAction
     void action(){
        // do stuff
     }
}

// put this after your `android{}` block.
android.applicationVariants.all { variant ->
    def taskName = "myTask_$variant.name"
    task "$taskName"(type: MyTask) << {
        // you can setup this task to various info regarding
        // variant
        variantName = variant.name
    }
    variant.assemble.dependsOn (taskName)
}

See Advance customization for more details of what you can extract from the variant variable.有关可以从variant变量中提取的内容的更多详细信息,请参阅高级定制

now you it will properly hookup your MyTask into to the chain.现在您将正确地将您的MyTask连接到链中。 Doing it this way should also cleanly handle building multiple flavors all at once as it creates a new instance of MyTask for each variant.以这种方式执行此操作还应该可以同时干净地处理构建多种风格,因为它会为每个变体创建一个新的 MyTask 实例。

Based on Shooky's answer and JLund's comment , this is what works for me.根据Shooky 的回答JLund 的评论,这对我有用 I have this code in my app build.gradle towards the end:我的应用程序 build.gradle 中最后有这段代码:

ext.getCurrentBuildType = {
    def isDebug = gradle.startParameter.taskRequests.any {
                            it.args.any { it.endsWith("Debug") } }
    return isDebug ? "Debug" : "Release"
}

Just call it afterEvaluate .只需调用它afterEvaluate Example:例子:

afterEvaluate {
    tasks.getByName("externalNativeBuild${ext.getCurrentBuildType()}")
         .dependsOn myOtherTask
}

Apparently, gradle.startParameter has plenty of info about current run.显然, gradle.startParameter有很多关于当前运行的信息。 Take a look at the doc .看看文档

The idea of executing a certain code based on the environment should be through dependency injection.基于环境执行某段代码的思路应该是通过依赖注入。


Take into account to use the following declaration only for exceptional configurations because in general it should not happen that in the code there are conditionals that make references to the environments.考虑将以下声明用于特殊配置,因为通常不会发生在代码中存在引用环境的条件。

build.gradle构建.gradle

android {

    def TRUE = "true"
    def FALSE = "false"
    def IS_DEV = "IS_DEV"
    def IS_RELEASE = "IS_RELEASE"

    defaultConfig {
        //...
        buildConfigField BOOLEAN, IS_DEV, FALSE
        buildConfigField BOOLEAN, IS_RELEASE, FALSE
    }

    buildTypes {
        debug {
            buildConfigField BOOLEAN, IS_DEV, TRUE
        }
        release {
            buildConfigField BOOLEAN, IS_RELEASE, TRUE
        }
    }

}

GL GL

正在运行 Gradle 任务 'assembleRelease'...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM