Ejecuta la tarea antes de la comstackción con el complemento Android Gradle

Tengo un archivo build.gradle muy simple con el siguiente contenido:

 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() } } 

Lo que quiero es ejecutar la tarea generateSources antes de que comience la comstackción java. Encontré varias soluciones para hacerlo, como compileJava.dependsOn("generateSources") , pero desafortunadamente dan un error:

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

No conozco a Gradle y no puedo entender qué pasa con este código. Entonces me gustaría saber cómo puedo solucionar este error.

Aparentemente, el complemento android no agrega una tarea compileJava (como el plugin java ). Puede verificar qué tareas están disponibles con gradle tasks --all , y elegir la correcta para su statement de dependencia (de lo contrario, correcta).

EDITAR:

Aparentemente, el complemento de android difiere la creación de tareas de tal manera que no se puede acceder con impaciencia como de costumbre. Una forma de superar este problema es postergar el acceso hasta el final de la fase de configuración :

 gradle.projectsEvaluated { compileJava.dependsOn(generateSources) } 

Lo más probable es que haya una forma más idiomática de resolver su caso de uso, pero al navegar rápidamente por los documentos del complemento de Android no pude encontrar uno.

La forma correcta de ejecutar una tarea antes de la comstackción de Java en Android es hacer que una tarea de comstackción para cada variante dependa de su tarea.

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

Puede ver la ejecución de la tarea en la tarea de ejecución de la terminal, por ejemplo, gradle assemble . Prueba este, se inicia prácticamente antes que nada.

 gradle.projectsEvaluated { preBuild.dependsOn(generateSources) } 

Editar , esto puede no funcionar en Android Studio, ya que Android Gradle DSL no tiene un método evaluado por projectsEvaluated .

Prueba esto:

 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 

Las dos últimas líneas son opcionales: invocarán la tarea “generateSources” al ejecutar un gradle clean

Para aquellos que tienen una comstackción de proyectos múltiples y necesitan ejecutar una tarea para cada proyecto antes de que se construyan (pero también debería estar bien si solo tienes el proyecto de la aplicación), puedes escribir la tarea en el script de configuración de comstackción raíz. el cierre de allprojects los allprojects y la ejecución de la tarea allí.

En el proyecto raíz build.gradle :

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

Se ejecutará para cada variante de comstackción también.

Gradle 4.1