web-dev-qa-db-fra.com

Exécuter la tâche avant la compilation en utilisant Android Plugin Gradle

J'ai un fichier build.gradle Très simple avec le contenu suivant:

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

Ce que je veux, c'est d'exécuter la tâche generateSources avant Java est lancée. J'ai trouvé plusieurs solutions pour le faire, comme compileJava.dependsOn("generateSources"), mais malheureusement, elles donnent une erreur:

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

Je ne connais pas Gradle et ne peux pas comprendre ce qui ne va pas avec ce code. Je voudrais donc savoir comment résoudre cette erreur.

35
Michael

La bonne façon d'exécuter une tâche avant Java sur Android est de faire dépendre une tâche de compilation pour chaque variante).

afterEvaluate {
  Android.applicationVariants.all { variant ->
    variant.javaCompiler.dependsOn(generateSources)
  }
}
24
Michael

Apparemment, le plugin Android n'ajoute pas de tâche compileJava (comme le ferait le plugin Java). Vous pouvez vérifier quelles tâches sont disponibles avec gradle tasks --all, et choisissez la bonne pour votre déclaration de dépendance (sinon correcte).

ÉDITER:

Apparemment, le plugin Android diffère la création des tâches de telle manière qu'elles ne sont pas accessibles avec impatience comme d'habitude. Une façon de surmonter ce problème est de différer l'accès jusqu'à la fin de la phase de configuration :

gradle.projectsEvaluated {
    compileJava.dependsOn(generateSources)
}

Il y a de fortes chances qu'il existe un moyen plus idiomatique pour résoudre votre cas d'utilisation, mais en parcourant rapidement les documentation du plugin Android je n'ai pas pu en trouver un.

28

Vous pouvez voir l'exécution des tâches dans le terminal en cours d'exécution, par exemple gradle assemble. Essayez celui-ci, il commence pratiquement avant tout.

gradle.projectsEvaluated {
     preBuild.dependsOn(generateSources)
}

Modifier , cela peut ne pas fonctionner dans Android Studio, comme le Android Gradle DSL n'a pas de méthode projectsEvaluated.

13
Gennadiy Ryabkin

Essaye ça:

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

Les deux dernières lignes sont facultatives - elles invoqueront la tâche "generateSources" lors de l'exécution d'un nettoyage gradle

4
Phileo99

Pour ceux qui ont une construction multi-projets et qui doivent exécuter une tâche pour chaque projet avant leur construction (mais cela devrait également être correct si vous n'avez que le projet d'application), vous pouvez écrire la tâche dans le script de configuration de la construction racine à l'intérieur la fermeture de allprojects et l'exécution de la tâche là-bas.

Dans le projet racine build.gradle:

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

Il sera également exécuté pour chaque variante de build.

Gradle 4.1

0
devrocca