Запустить задачу перед компиляцией с помощью плагина Android Gradle

У меня есть очень простой 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()
    }
}

Я хочу запустить generateSources задачу до начала компиляции java. Я нашел несколько решений, как это сделать, например compileJava.dependsOn("generateSources"), но, к сожалению, они выдают ошибку:

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

Я не знаю Gradle и не могу понять, что не так с этим кодом. Итак, я хотел бы знать, как я могу исправить эту ошибку.


person Michael    schedule 31.05.2013    source источник
comment
Думаю, в этой теме вы найдете решение [зависимость задачи AssemblyRelease - запросить пароль хранилища ключей] [1] [1]: stackoverflow.com/questions/17144878/   -  person skyrylyuk    schedule 15.09.2013


Ответы (5)


Очевидно, плагин android не добавляет задачу compileJava (как плагин java). Вы можете проверить, какие задачи доступны с gradle tasks --all, и выбрать подходящую для вашего (в противном случае правильного) объявления зависимости.

РЕДАКТИРОВАТЬ:

Судя по всему, плагин android откладывает создание задач таким образом, что к ним невозможно получить доступ, как обычно. Один из способов решить эту проблему - отложить доступ до конца фазы настройки:

gradle.projectsEvaluated {
    compileJava.dependsOn(generateSources)
}

Скорее всего, есть более идиоматический способ решить ваш вариант использования, но быстро просмотреть Android документы плагина, мне не удалось его найти.

person Peter Niederwieser    schedule 31.05.2013
comment
Что не работает и каково точное сообщение об ошибке? - person Peter Niederwieser; 31.05.2013
comment
Проблема та же, что и раньше: Could not find property 'compileDebug' on root project 'Android'. - person Michael; 31.05.2013
comment
А вы проверили, что compileDebug существует? gradle compileDebug работает? Вы добавили объявление зависимости внизу сценария сборки? Вы также можете попробовать tasks.compileDebug, но это не должно иметь значения. - person Peter Niederwieser; 31.05.2013
comment
gradle compileDebug отлично работает. Внизу файла я добавил compileDebug.dependsOn("generateSources"). Когда я пишу tasks.compileDebug вместо compileDebug, gradle выдает ошибку Could not find property 'compileDebug' on task set. - person Michael; 31.05.2013
comment
Просматривая документацию плагина Android, я понял, что он работает совсем не так, как большинство других плагинов. gradle.projectsEvaluated { tasks.compileDebug.dependsOn(generateSources) } работает? Возможно, есть более идиоматический способ. - person Peter Niederwieser; 31.05.2013
comment
Ага, вроде работает! Не могли бы вы добавить это к ответу и объяснить, что это значит? - person Michael; 31.05.2013
comment
Потрясающе - мы занимаемся этим уже несколько дней, не понимая, почему обычная функция зависит от заранее определенных задач. Теперь я наконец могу добавить зависимость к connectedCheck. - person slott; 18.12.2013
comment
Привет, Питер Нидервизер, это дает мне ошибку ниже. Не удалось найти свойство compileJava на com.android.build.gradle.AppExtension_Decorated@44b35022. - person Dhrupal; 04.03.2014
comment
Название задачи, похоже, изменилось на _ 1_. - person ento; 17.06.2014
comment
У меня есть задача, которую нужно запустить перед сборкой Android. Задача копирует файл jar в каталог libs. Почему-то для сборки Android это случилось слишком поздно. Моя сборка Android всегда терпит неудачу с первого раза после чистки. Затем во второй раз работает (так как там есть jar-файл). Как быстро запустить задачу, которая копирует файл jar? - person treesAreEverywhere; 07.08.2014
comment
@PeterNiederwieser есть шанс обновить свой ответ? Кажется, это уже устарело. (Извините, если это звучит немного грубо, это не так) - person treesAreEverywhere; 07.08.2014
comment
Почему он устарел? - person Peter Niederwieser; 07.08.2014
comment
Что ж, ваш ответ по-прежнему говорит о compileJava.dependsOn (...), который не работает, как обсуждалось в комментариях. - person Greg Ennis; 11.09.2014
comment
./gradlew tasks --all в каталоге проекта также показывает описание задачи. - person Martin Zeitler; 10.08.2016

Правильный способ запустить задачу перед компиляцией Java на Android - сделать задачу компиляции для каждого варианта зависимой от вашей задачи.

afterEvaluate {
  android.applicationVariants.all { variant ->
    variant.javaCompiler.dependsOn(generateSources)
  }
}
person Michael    schedule 31.03.2016
comment
Куда вы здесь называете свою индивидуальную задачу? - person IgorGanapolsky; 08.08.2016
comment
generateSources - это настраиваемая задача. И javaCompiler задачи становятся зависимыми от generateSources. - person Michael; 10.08.2016
comment
Я получаю сообщение об ошибке: Не удалось найти свойство "android" в корневом проекте - person IgorGanapolsky; 17.08.2016
comment
Перед этим кодом вы должны применить плагин Android. - person Michael; 17.08.2016
comment
@ Майкл, как ты это делаешь? Я использую Android Studio - person Compaq LE2202x; 11.09.2017
comment
Вам просто нужно поместить этот код в свой build.gradle файл. - person Michael; 11.09.2017
comment
@Michael Как это сделать для нескольких задач? - person Compaq LE2202x; 19.09.2017
comment
Вы можете позвонить variant.javaCompiler.dependsOn(taskName) для каждой задачи. Другой подход - иметь цепочку задач и вызывать variant.javaCompiler.dependsOn(taskName) для корневой. - person Michael; 19.09.2017
comment
variant.javaCompiler устарело, следует использовать variant.javaCompileProvider.get() - person Khongor Bayarsaikhan; 14.01.2020

Вы можете увидеть выполнение задачи в запущенной задаче терминала, например gradle assemble. Попробуйте этот, он запускается практически раньше всего.

android {
    ...
    gradle.projectsEvaluated {
         preBuild.dependsOn(generateSources)
    }
    ...
}

Изменить, это может не работать в Android Studio, поскольку Android Gradle DSL не имеет projectsEvaluated метода.

person Gennadiy Ryabkin    schedule 23.06.2014
comment
Какие? Я получаю сообщение об ошибке: Не удалось найти свойство preBuild в корневом проекте - person IgorGanapolsky; 17.08.2016
comment
Так что, вероятно, его сейчас нет в более новых версиях Gradle - person Gennadiy Ryabkin; 17.08.2016
comment
Существовал ли он когда-либо в Android Studio? Или вы вообще говорили о Gradle ... - person IgorGanapolsky; 17.08.2016
comment
Его использовали в одном из моих проектов Игорь - person Gennadiy Ryabkin; 22.08.2016
comment
@IgorGanapolsky просто поместил prebuild.dependsOn ('someTask') в блок android {}, работает как шарм. Не нужно вызывать projectsEvaluated. - person Merk; 06.10.2016
comment
tsk ... tsk .. потратил часы на то, чтобы заставить задачу запустить, потому что я помещал связанный код вне блока android {} - person lasec0203; 09.06.2020
comment
@ lasec0203 спасибо, что указали на это. Я внес соответствующую правку, - person Gennadiy Ryabkin; 10.06.2020

Попробуй это:

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.

person Phileo99    schedule 17.02.2016
comment
Я получаю сообщение об ошибке: Не удалось найти свойство preBuild в проекте: app - person IgorGanapolsky; 17.08.2016
comment
Любое предложение, которое может получить информацию, связанную с типом сборки, в задаче Gradle 'generateSources' - person Killer; 28.03.2019

Для тех, у кого есть многопроектная сборка и которым необходимо запускать задачу для каждого проекта до их сборки (но это также должно быть нормально, если у вас есть только проект приложения), вы можете написать задачу в сценарии конфигурации корневой сборки внутри allprojects закрытие и выполнение задачи прямо здесь.

В корневом проекте build.gradle:

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

Он также будет выполняться для каждого варианта сборки.

Gradle 4.1

person devrocca    schedule 16.02.2018
comment
Это плохо, так как он будет запускаться при каждом вызове. Включая такие вещи, как чистота, что, вероятно, не то, что вам нужно. В зависимости от того, что он делает, он может запускать проверки обновлений, чтобы делать больше вещей. - person ottago; 04.05.2018