Saturday, 13 July 2013

Building Android projects with Gradle

I notice there is a lot of interest at the moment in the new Android Studio development environment, launched at the recent Google IO event. I have often found Eclipse to be often slow and lacking in robustness, so an alternative IDE being supported for Android development is welcome news. Upon reading about the changes in more detail, another significant piece of news is the new build system for Android projects, based around Gradle. So, I decided to take a look at Gradle in more detail.

Here are some intended benefits for the use of Gradle for Android projects:
- the use of the same build system whether in the IDE or the command line
- the benefits of improved dependency management
- easier integration into automated build systems

There is an additional advantage thanks to the new packaging format for Android libraries, the "aar" format. Previously, android libraries have usually been imported into the IDE so that their resources could be compiled into the app. But now Android libraries can be included much more easily, in the same way that "jar" files have been included in Java projects for years. This particular feature is long overdue but very welcome indeed.

Here is a gradle build script from one of my projects.
buildscript { //define the path to some pre-existing JAR libraries //required by the project LIBS_DIR = "../../../libs" //the android plugin for gradle should be obtained from the maven central repository repositories { mavenCentral() } dependencies { classpath '' } } //declare the project is an android build apply plugin: 'android' dependencies { //also use the local maven repository to //look for dependencies repositories { mavenLocal() } //these are some jar files that are required by the app compile files("${LIBS_DIR}/hiscore/hiscore.jar") compile files("${LIBS_DIR}/GoogleAnalytics/libGoogleAnalytics.jar") //this is an android library (using the "aar") format which I have put in my local maven repository compile ('com.mopub.mobileads:mopub-android-sdk:unknown') } //the project definitions for the android build android { compileSdkVersion 15 buildToolsVersion "17.0.0" //The source paths below are not the new recommended project structure //I am still using the default Eclipse-like structure sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] resources.srcDirs = ['src'] aidl.srcDirs = ['src'] renderscript.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] } instrumentTest.setRoot('tests') } //declare the details for creating a signed release version signingConfigs { release { storeFile file("../keys/android.keystore") storePassword "######" keyAlias "######" keyPassword "######" } } //declare the release build should run proguard and perform signing buildTypes { release { runProguard true proguardFile getDefaultProguardFile('proguard-android.txt') proguardFile 'proguard.cfg' signingConfig signingConfigs.release } } }
Build the app from the command line can be done by running one of these commands:
gradle assembleDebug #for debug build gradle assembleRelease #for release build
I have previously used Maven for some projects, and found it very useful for managing project configuration, especially dependencies. But I also found it lacked flexibility for those cases where you need to customize your build for a special case. While in theory you could write your own Maven plugin, in practise most users won't do this and instead rely only on existing well-supported plugins. I often found myself using Ant rather than Maven, because it provides increased flexibility where you need to do some specific operation in a project, such as copy or modify a source file in some way.

Gradle appears to offer the best of both worlds: comprehensive support for a wide variety of common use cases via plugins, the same dependency support as Maven, but also the flexibility to allow custom modifications to your build script to suit whatever is the need.

I am convinced the Gradle is the way to go for Android builds. There are plenty of other cool features too, such as build "flavors", that I haven't even mentioned. I think this adoption of Gradle by Google is a hugely important step forward for Android. Now, I just need to convert over all my other projects to use Gradle too...