Previously in this series we’ve looked at various aspects of the new Android Gradle build system. But what happens if the Android tools do not quite do what we require? In this article we’ll have a look at how we can extend and customise the Gradle build process.
A Gradle build consists of a series of tasks which are run in a particular sequence. When we have looked at the output from running our builds in previous articles, each of these tasks gets logged during the build process. The Android plugin defines a number of its own specific tasks, and it is these that are executed in sequence to perform an Android build.
We discussed previously how some aspects of what we covered in this series is specific to the Android plugin (such as build variants), and others are a feature of Gradle itself. Adding custom tasks falls in the latter category, and works independently of the Android plugin, although this does not stop us from customising the Android plugin build process as we shall see.
We can actually query Gradle for the tasks which have been defined for a particular build by executing the following command in the root project:
$ ./gradlew -q tasks ------------------------------------------------------------ All tasks runnable from root project ------------------------------------------------------------ Android tasks ------------- androidDependencies - Displays the Android dependencies of the project signingReport - Displays the signing info for each variant Build tasks ----------- assemble - Assembles all variants of all applications and secondary packages. assembleComplex - Assembles all builds for flavor Complex assembleComplexDebug - Assembles the Debug build for flavor Complex assembleComplexRelease - Assembles the Release build for flavor Complex assembleComplexTest - Assembles the Test build for the ComplexDebug build assembleDebug - Assembles all Debug builds assembleRelease - Assembles all Release builds assembleSimple - Assembles all builds for flavor Simple assembleSimpleDebug - Assembles the Debug build for flavor Simple assembleSimpleRelease - Assembles the Release build for flavor Simple assembleSimpleTest - Assembles the Test build for the SimpleDebug build assembleTest - Assembles the Test build for the Debug build build - Assembles and tests this project. buildDependents - Assembles and tests this project and all projects that depend on it. buildNeeded - Assembles and tests this project and all projects it depends on. clean - Deletes the build directory. Build Setup tasks ----------------- setupBuild - Initializes a new Gradle build. [incubating] Help tasks ---------- dependencies - Displays all dependencies declared in root project 'GradleTestProject'. dependencyInsight - Displays the insight into a specific dependency in root project 'GradleTestProject'. help - Displays a help message projects - Displays the sub-projects of root project 'GradleTestProject'. properties - Displays the properties of root project 'GradleTestProject'. tasks - Displays the tasks runnable from root project 'GradleTestProject' (some of the displayed tasks may belong to subprojects). Install tasks ------------- installComplexDebug - Installs the Debug build for flavor Complex installComplexTest - Installs the Test build for the ComplexDebug build installSimpleDebug - Installs the Debug build for flavor Simple installSimpleTest - Installs the Test build for the SimpleDebug build installTest - Installs the Test build for the Debug build uninstallAll - Uninstall all applications. uninstallComplexDebug - Uninstalls the Debug build for flavor Complex uninstallComplexRelease - Uninstalls the Release build for flavor Complex uninstallComplexTest - Uninstalls the Test build for the ComplexDebug build uninstallSimpleDebug - Uninstalls the Debug build for flavor Simple uninstallSimpleRelease - Uninstalls the Release build for flavor Simple uninstallSimpleTest - Uninstalls the Test build for the SimpleDebug build uninstallTest - Uninstalls the Test build for the Debug build Verification tasks ------------------ check - Runs all checks. connectedCheck - Runs all device checks on currently connected devices. connectedInstrumentTest - Installs and runs the tests for Build 'Debug' on connected devices. connectedInstrumentTestComplexDebug - Installs and runs the tests for Build 'ComplexDebug' on connected devices. connectedInstrumentTestSimpleDebug - Installs and runs the tests for Build 'SimpleDebug' on connected devices. deviceCheck - Runs all device checks using Device Providers and Test Servers. deviceInstrumentTest - Installs and runs instrumentation tests using all Device Providers. To see all tasks and more detail, run with --all. $
You can see the clean
and assemble
tasks that we have been invoking from the command line when performing builds. An interesting thing to note is that we can see tasks which have been created because of the custom build variants (Simple and Complex) which we added in the previous article. So adding build variants automatically created some related tasks.
Adding custom tasks is quite easy. The simplest way of creating a task is to create a Groovy task in build.gradle
within our GradleTest
project:
apply plugin: 'android' dependencies { compile 'com.android.support:support-v4:18.0.0' } android { compileSdkVersion rootProject.compileSdkVersion buildToolsVersion rootProject.buildToolsVersion defaultConfig { minSdkVersion rootProject.minSdkVersion targetSdkVersion rootProject.targetSdkVersion } productFlavors { simple { packageName "com.stylingandroid.gradle.simple" } complex { packageName "com.stylingandroid.gradle.complex" dependencies { complexCompile project(':GradleLibrary') } } } } task custom(description: 'This is our custom task') << { task -> println "Running task ${task.name}" }
This is a really simple task which will simply print out a status string when it runs.
We can now see this in our tasks list:
$ ./gradlew -q tasks . . . Other tasks ----------- custom - This is our custom task To see all tasks and more detail, run with --all. $
We can now invoke this task from the command line:
$ ./gradlew --daemon custom :GradleTest:custom Running task custom BUILD SUCCESSFUL Total time: 1.771 secs $
We can see that the the task is running and printing its status string.
That’s all well and good, but defining standalone tasks don’t help us much. In the final article in this series we’ll look at how we can attach our task to the build lifecycle so it gets invoked as part of the build.
The source code for this article is available here.
© 2013 – 2014, Mark Allison. All rights reserved.
Copyright © 2013 Styling Android. All Rights Reserved.
Information about how to reuse or republish this work may be available at http://blog.stylingandroid.com/license-information.