Плагин Gradle для Android: подключение к задаче после компиляции для всех вариантов продукта

Мне нужно выполнить свой собственный код (через javaexec) после того, как мой проект для Android был скомпилирован Gradle, но до того, как он будет упакован в apk (и фактически до того, как ресурсы будут перемещены в конечный пункт назначения). Поэтому я использовал:

gradlew tasks --all

Чтобы получить список доступных задач. Я использую ароматы продуктов, поэтому почти все задачи имеют название аромата где-то посередине, например:

собратьFlavorA

or

установитьFlavorB

так далее...

Что я могу сделать прямо сейчас, так это выполнить свою собственную задачу до начала компиляции, подключившись к задаче preBuild:

preBuild <<{
    //Do some stuff
}

Вышеприведенное вызывается для каждого варианта сборки, и это именно то, что я хочу. Однако, когда я пытаюсь сделать то же самое с задачей сборки или задачей сборки:

assemble <<{
    //Get's never executed
}

build <<{
    //Get's never executed
}

Приведенный выше код никогда не выполняется, независимо от того, какой вариант продукта я создаю. Глядя на список зависимостей для releaseFlavorA:

myapp:assembleFlavorARelease - Assembles the Release build for flavor FlavorA [library:bundleRelease]
    myapp:checkFlavorAReleaseManifest
    myapp:compileFlavorAReleaseAidl
    myapp:compileFlavorAReleaseJava
    myapp:compileFlavorAReleaseNdk
    myapp:compileFlavorAReleaseRenderscript
    myapp:dexFlavorARelease
    myapp:generateFlavorAReleaseAssets
    myapp:generateFlavorAReleaseBuildConfig
    myapp:generateFlavorAReleaseResValues
    myapp:generateFlavorAReleaseResources
    myapp:generateFlavorAReleaseSources
    myapp:lintVitalFlavorARelease - Runs lint on just the fatal issues in the FlavorARelease build
    myapp:mergeFlavorAReleaseAssets
    myapp:mergeFlavorAReleaseResources
    myapp:packageFlavorARelease
    myapp:preFlavorADebugBuild
    myapp:preFlavorAReleaseBuild
    myapp:preAltdorfDebugBuild
    myapp:preAltdorfReleaseBuild
    myapp:preBerlinDebugBuild
    myapp:preBerlinReleaseBuild
    myapp:preBuild
    myapp:prepareFlavorAReleaseDependencies
    myapp:prepareComAndroidSupportAppcompatV71910Library - Prepare com.android.support:appcompat-v7:19.1.0
    myapp:prepareTrunkGradleLibraryUnspecifiedLibrary - Prepare trunk-gradle:library:unspecified
    myapp:processFlavorAReleaseJavaRes
    myapp:processFlavorAReleaseManifest
    myapp:processFlavorAReleaseResources
    myapp:validateReleaseSigning
    myapp:zipalignFlavorARelease

Я вижу только preBuild, но не собираю и не строю, что странно, так как он отображается при запуске

gradlew tasks 

Но большинство методов в приведенном выше списке зависят от разновидности, и я не хочу иметь одну и ту же задачу 20 раз, потому что у меня есть 20 разных разновидностей... Итак, как я могу выполнить свои необходимые задачи после завершения компиляции, но APK еще не упакован для всех вкусов? Что-то типа:

//I know there is no task called "postCompile" - so anything post compiling and pre-packaging would be fine
postCompile << {
    //Do something that needs to be done for all flavors
}

EDIT Поэтому я перепроверил вывод командной строки при сборке customerA, например, с помощью:

gradlew assembleCustomerARRelease

    C:\Users\user\workspace\android\trunk-gradle>gradlew assembleCustomerARelease
:library:compileLint
:library:copyReleaseLint UP-TO-DATE
:library:mergeReleaseProguardFiles UP-TO-DATE
:library:preBuild
:library:preReleaseBuild
:library:checkReleaseManifest
:library:preDebugBuild
:library:preDebugTestBuild
:library:prepareComAndroidSupportAppcompatV71910Library UP-TO-DATE
:library:prepareReleaseDependencies
:library:compileReleaseAidl UP-TO-DATE
:library:compileReleaseRenderscript UP-TO-DATE
:library:generateReleaseBuildConfig UP-TO-DATE
:library:generateReleaseAssets UP-TO-DATE
:library:mergeReleaseAssets UP-TO-DATE
:library:generateReleaseResValues UP-TO-DATE
:library:generateReleaseResources UP-TO-DATE
:library:mergeReleaseResources UP-TO-DATE
:library:processReleaseManifest UP-TO-DATE
:library:processReleaseResources UP-TO-DATE
:library:generateReleaseSources UP-TO-DATE
:library:compileReleaseJava UP-TO-DATE
:library:processReleaseJavaRes UP-TO-DATE
:library:packageReleaseJar UP-TO-DATE
:library:compileReleaseNdk UP-TO-DATE
:library:packageReleaseJniLibs UP-TO-DATE
:library:packageReleaseLocalJar UP-TO-DATE
:library:packageReleaseRenderscript UP-TO-DATE
:library:packageReleaseResources UP-TO-DATE
:library:bundleRelease UP-TO-DATE
:myapp:preBuild
Path to customer file: C:\Users\user\workspace\android\trunk-gradle\myapp\src\CustomerA\res\xml\customer.xml
Selected server: release
:myapp:preCustomerAReleaseBuild
:myapp:checkCustomerAReleaseManifest
:myapp:preCustomerADebugBuild
:myapp:preCustomerBDebugBuild
:myapp:preCustomerBReleaseBuild
:myapp:preCustomerCDebugBuild
:myapp:preCustomerCReleaseBuild
:myapp:prepareComAndroidSupportAppcompatV71910Library UP-TO-DATE
:myapp:prepareTrunkGradleLibraryUnspecifiedLibrary UP-TO-DATE
:myapp:prepareCustomerAReleaseDependencies
:myapp:compileCustomerAReleaseAidl UP-TO-DATE
:myapp:compileCustomerAReleaseRenderscript UP-TO-DATE
:myapp:generateCustomerAReleaseBuildConfig UP-TO-DATE
:myapp:generateCustomerAReleaseAssets UP-TO-DATE
:myapp:mergeCustomerAReleaseAssets UP-TO-DATE
:myapp:generateCustomerAReleaseResValues UP-TO-DATE
:myapp:generateCustomerAReleaseResources UP-TO-DATE
:myapp:mergeCustomerAReleaseResources UP-TO-DATE
:myapp:processCustomerAReleaseManifest UP-TO-DATE
:myapp:processCustomerAReleaseResources UP-TO-DATE
:myapp:generateCustomerAReleaseSources UP-TO-DATE
:myapp:compileCustomerAReleaseJava UP-TO-DATE
:myapp:lintVitalCustomerARelease
//Some logoutput from the dex-ing task not really relevant in this case
:myapp:dexCustomerARelease UP-TO-DATE
:myapp:processCustomerAReleaseJavaRes UP-TO-DATE
:myapp:validateReleaseSigning
:myapp:packageCustomerARelease UP-TO-DATE
:myapp:zipalignCustomerARelease UP-TO-DATE
:myapp:assembleCustomerARelease

BUILD SUCCESSFUL

Total time: 25.451 secs

Итак, основываясь на приведенном выше выводе сборки, я бы предположил, что preBuild действительно происходит после фазы компиляции? Поскольку он указан после compileReleaseJava и других задач компиляции. Если это так, то мне достаточно требований "preBuild".

ОБНОВЛЕНИЕ 04.02.2015

Вопрос остается открытым, но я изменил свой код, чтобы он больше не зависел от него. Вместо того, чтобы пытаться использовать класс java, который должен быть сначала скомпилирован моим проектом, я создал другой проект для этого класса, который генерирует файл jar, который, в свою очередь, я думаю, использовать - подробности можно найти здесь:

https://stackoverflow.com/a/28303047/1041533

Тем не менее, я думаю, что все еще может быть интересно узнать ответ на этот вопрос.


person AgentKnopf    schedule 30.01.2015    source источник
comment
Я не уверен, что вы хотите, чтобы эта задача делала. Что-то вроде этого помогает? stackoverflow .com/questions/25997866/ Имеет смысл пытаться что-то делать с каждым APK по мере его создания, но вы можете черпать из этого вдохновение.   -  person Scott Barta    schedule 30.01.2015
comment
@ScottBarta Я наткнулся на ссылку выше, о которой вы упоминали ранее :). Это было полезно для именования apk-файла, но в этом случае хук должен быть после компиляции (которой, как я думаю, может быть preBuild — несмотря на то, что имя предполагает обратное? Подробности см. в разделе «Редактировать»), но до того, как все это будет упаковано в apk. файл и, на самом деле, фрагмент из ссылки фактически повторяет вывод после того, как он был упакован.   -  person AgentKnopf    schedule 31.01.2015


Ответы (1)


Вы не можете расширить такие задачи сборки и сборки, потому что они заменяются соответствующими задачами, связанными с вариантом сборки, прямо перед фазой выполнения Gradle. Например: сборка становится assembleRelease.

Тем не менее, вы все еще можете подключиться к процессу сборки, когда граф сборки собирается вместе. Если вы хотите выполнить свой собственный код прямо перед задачей пакета, вы можете использовать этот фрагмент:

task doStuff << {
    // Do stuff
}

tasks.whenTaskAdded { theTask ->
    if (theTask.name.contains('package')) {
        theTask.dependsOn 'doStuff'
    }
}

Этот код не делает различий между вариантами сборки; вы можете сделать это в условии if, если это необходимо.

person kevinpelgrims    schedule 05.04.2015