What is Gradle and why using it now?

Gradle is an advance build toolkit that manages dependencies and allows defining our custom build logic.

If Ant and Mave already exist, why Gradle now?

  • Ant: It was the first modern build tool and it became the most popular one for Java projects. It has a small learning curve. Configured by XML, which causes it to be unmanageable as it grows a bit. It is also based on an idea of procedural programming, that does not fit well with XML hierarchical nature. It uses Apache Ivy for manage online dependencies..
  • Maven: emerges later to improve Ant problems. Even though it also uses XML too, it simplifies tasks creation compared to Ant. It allows online dependencies download before Ant added Ivy. It is thougher for dependencies management, and customizing scripts is more complex than in Ant. Also, its XML format makes it difficult to customize.

 

However, Gradle combines the best of each one, has the power and flexibility of Ant with the ease of use of Maven, but without XML!! it has a Domain Specific Language based in Groovy (a language supported by Java Virtual Machine), scripts are shorter and clearer, less boilerplate. Gradle supports the automatization of downloads and the configuration of dependencies of project/libraries (supports Maven and Ivy repositories). It is very flexible, allows to use good practices but does not  force the way of doing things. Plugins can expose its own DSL and API to be reused.

 

Android Studio adopted Gradle in 2014 as projects build tool, and added some extra features for Android. Uses a wrapper for plugin integration and runs it independently (it could compile app from Android Studio as well as from the command line).

Currently Gradle version is on v4.2, different Android plugins allows to select different versions:

 

Android Plugin Gradle version
1.0.0 – 1.1.3 2.2.1 – 2.3
1.2.0 – 1.3.1 2.2.1 – 2.9
1.5.0 2.2.1 – 2.13
2.0.0 – 2.1.2 2.10 – 2.13
 2.1.3 – 2.2.3 2.14.1 +
2.3.0 + 3.3 +

 

Basic concepts of Gradle

 

Build types

Defines how  an application is going to be packaged for environment (local, debug, staging, quality, release, …). It controls fields like debug flag, minify with proguard, signing config, suffix…

 

Product flavors

Defines a custom version of the application. The same project could have different flavor (free, premium, Google store, Amazon store, etc.)

When a project declares different flavors, they extend the main configuration having its own code and resources.

Although different flavors may be different applications, it is better to use project libraries. Flavors are designed to help when differences are very small.

 

Variants

with flavor → variant = build type + product flavor

without flavor → variant = build type

 

free premium
local freeLocal  premiumLocal
quality freeQuality premiumQuality
staging freeStaging premiumStaging
release freeRelease premiumRelease

 

BuildConfig

Dynamic values can be created depending on variant in order to configure the application for different environments. In building time, when BuildConfig.java is created, it has constants used for a given variant, this class is accessible along the app to apply configuration to startup database, network access, etc:

 

 

 

Dependencies

Sometimes we have dependencies in our packages that causes conflicts in their transitive dependencies. A good solution is to exclude specific dependencies of a module:

or in multiple dependencies, exclude a lib from all of them:

 

It is possible to force Gradel to use an specific version whenever it finds a conflict.

 

API version

In the API configuration of Gradle, it is very important to indicate the versions to be compiled, target, dependencies libraries, etc.:

  • minSdkVersion: the min. Android version on where the app can run.
  • compileSdkVersion: API version on which APK is built. Major dependencies libraries API number must be equal to compileSdkVersion .
  • buildToolsVersion: builder version (aapt, dx, renderscript compiler, etc…) that is going to be used. For each API level (starting at 18) there are versions “.0.0” that could be increased to use improvements without change major API. Major buildToolsVersion must be equal or greater than compileSdkVersion.
  • targetSdkVersion: version which the app is targeted by performance, optimization, etc. It is usually the same as compileSdkVersion, but not bigger.

 

Android Model

Since Android Studio 1.5, there is a new integrated component with Gradle that shows configuration for all BuildTypes, ProductFlavors, Variants, BuildConfig, ResValues, etc.

 

In Android Studio we can select Android Model, in Variants → [ProductFlavor] → Artifacts → _main  we have all generated configuration when Gradle is compiled:

  • BuildConfigFields: all constants from generated class BuildConfig.java

Android - Gigigo

  • Outputs: manifest, output APK
  • ResValues: generated resvalues

Android Model - Gigigo

  • Sources: app folder structure (manifest, java, jni, res, assets, …)

 

 

Wrapper

Gradle is auto-installable , by its wrapper, a specific version can be selected. Gradle versions and Android Gradle Plugin version do not match, so you should stay alert.

There are two ways to execute Gradle on computer: locally installed or by a wrapper inside each project. It can be changed at Preferences → Build Tools → Gradle. We always use project wrapper to build, thus avoid problems with different developer computers.

Different wrapper Gradle version can be specified, go to this file gradle/wrapper/gradle-wrapper.properties and change the property:

 

or by Project Structure → Project changing Gradle version.

 

Offline

Everytime project Gradle is synchronized, it downloads libraries from web. If we do not want to synchronize Gradle by default, or we have no network connection, we can select at Preferences → Build Tools → Gradle → Offline work to work offline and save dependencies.

 

Conclusion

Automatization of specific task is something very important to take care of. Changing environments to test application against staging, quality or release server. Backend urls for different endpoints, id for Facebook or analytics. All this can take time out of developing and is very prone to failures. Before Gradle, we commented/uncommented lines, used different .java for each flavor to change environment configuration, or introduced String values for BuildConfig escaping the quotes, etc.

To avoid this, some time ago we modified projects build procedure to automate them with Gradle. Now enviroment change, test configuration, Jenkins integration for CI/CD is faster and easier.

Although we are continually improving it, you can see a base here

 

On the next blog post we will see the advanced Gradle configuration we use at Gigigo and how to customize it.

Senior Developer & Android Team Leader en Gigigo. Tri-Fada & Babies Developer 👦👧👧