使用Android Gradle插件在编译之前运行任务

时间:2013-05-31 08:34:48

标签: android gradle android-build

我有一个非常简单的build.gradle文件,其中包含以下内容:

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:0.4.1'
    }
}

apply plugin: 'android'

android {
    buildToolsVersion "17.0.0"
    compileSdkVersion 17

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }
    }
}

task generateSources {
    doFirst {
        def script = "python GenerateSources.py".execute()
        script.in.eachLine {line -> println line}
        script.err.eachLine {line -> println "ERROR: " + line}
        script.waitFor()
    }
}

我想要的是在启动Java编译之前运行generateSources任务。我找到了几个解决方法,如compileJava.dependsOn("generateSources"),但不幸的是他们给出了一个错误:

A problem occurred evaluating root project 'Android'.
> Could not find property 'compileJava' on root project 'Android'.

我不知道Gradle,也无法理解这段代码有什么问题。所以我想知道如何解决这个错误。

5 个答案:

答案 0 :(得分:27)

显然,android插件不会添加compileJava任务(就像java插件一样)。您可以使用gradle tasks --all检查哪些任务可用,并为您的(否则正确)依赖声明选择正确的任务。

编辑:

显然,android插件推迟创建任务,以至于无法像往常一样急切地访问它们。解决此问题的一种方法是将访问推迟到配置阶段结束

gradle.projectsEvaluated {
    compileJava.dependsOn(generateSources)
}

有可能有一种更惯用的方式来解决您的用例,但很快就浏览Android plugin docs我找不到一个。

答案 1 :(得分:24)

在Android上进行Java编译之前运行任务的正确方法是为每个变量创建编译任务取决于您的任务。

afterEvaluate {
  android.applicationVariants.all { variant ->
    variant.javaCompiler.dependsOn(generateSources)
  }
}

答案 2 :(得分:13)

您可以在终端运行任务中看到任务执行,例如gradle assemble。尝试这个,它几乎在任何事情之前开始。

gradle.projectsEvaluated {
     preBuild.dependsOn(generateSources)
}

修改,这可能无法在Android Studio中使用,因为Android Gradle DSL没有projectsEvaluated方法。

答案 3 :(得分:2)

试试这个:

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:0.4.1'
    }
}

apply plugin: 'android'

android {
    buildToolsVersion "17.0.0"
    compileSdkVersion 17

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }
    }
}

task generateSources {
    def script = "python GenerateSources.py".execute()
    script.in.eachLine {line -> println line}
    script.err.eachLine {line -> println "ERROR: " + line}
    script.waitFor()
}

project.afterEvaluate {
    preBuild.dependsOn generateSources
}

clean.dependsOn generateSources
clean.mustRunAfter generateSources

最后两行是可选的 - 它们将调用" generateSources"执行gradle clean时的任务

答案 4 :(得分:0)

对于那些拥有多项目构建并且需要在每个项目构建之前为其运行任务的人(但如果你只有app项目也应该没问题),你可以在root构建中编写任务allprojects闭包内的配置脚本,并在那里执行任务。

在根项目build.gradle中:

allprojects {
    repositories {
        // ...
    }
    // ...
    task mytask {
        doFirst {
            println project.projectDir.name
        }
    }
    mytask.execute()
}

它也将针对每个构建变体执行。

Gradle 4.1