I need to execute my own code (via javaexec), after my android project has been compiled by gradle but before it is packaged into an apk (and in fact, before the resources are moved to their final destination). So I used:
gradlew tasks --all
To get a list of available tasks. I am using product flavors, so almost all tasks have the name of a flavor somewhere in between like:
assembleFlavorA
or
installFlavorB
etc...
What I can do right now, is execute my own task before compiling starts by hooking into the preBuild task:
preBuild <<{
//Do some stuff
}
The above gets called for every build variant which is exactly what I want. However when I try the same with the assemble task or the build task:
assemble <<{
//Get's never executed
}
build <<{
//Get's never executed
}
The above code is never executed, regardless of which product flavor I am building. Looking at the dependency list for 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
I only see preBuild but neither assemble nor build, which is odd, since it's shown when running
gradlew tasks
But most methods in above list are flavor specific, and I don't want to have the same task 20 times, because I have 20 different flavors... So how can I execute my necessary tasks, once the compiling is done, but the APK hasn't been packaged yet for all flavors? Something like:
//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 So I rechecked the command line output when building customerA for instance via:
gradlew assembleCustomerARelease
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
So based on above build output, I'd assume that preBuild actually happens after the compile phase? As it's listed after compileReleaseJava and the other compile tasks. If this is the case, then "preBuild" would suffice for me requirements.
UPDATE 04.02.2015
The question remains open, but I have changed my code to no longer depend on it. Instead of trying to use a java class that would have to be compiled by my project first, I created another project for that class, which generates a jar file which in turn I think use - details can be found here:
https://stackoverflow.com/a/28303047/1041533
However - I think it might still be interesting to know the answer to this question.
You can't extend the assemble and build tasks like that because they are replaced with the appropriate build variant related tasks right before Gradle's execution phase. For example: assemble becomes assembleRelease.
You can still hook into the build process when the builds graph is being put together, though. If you want to execute your own code right before the package task, you can use this snippet:
task doStuff << {
// Do stuff
}
tasks.whenTaskAdded { theTask ->
if (theTask.name.contains('package')) {
theTask.dependsOn 'doStuff'
}
}
This code will make no distinction between build variants; you can do that in the if condition, if necessary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With