Build / Gradle

Gradle Build – Part 8

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.

gradle_logoA 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.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.