Affiliate links on Android Authority may earn us a commission.Learn more.

Build variants, Gradle tasks, and Kotlin: Mastering Gradle for Android

July 25, 2025

Does it feel like Android Studio packages and builds your apps, with very little input from you?

Behind the scenes, Android Studio uses theGradleautomated build toolkit, and although it’s possible to run Gradle with very little (if any) manual configuration, Gradle has much more to offer than what’s available out-of-the-box!

Article image

In this article, I’ll show you how to modify Android’s build process, by making changes to your Gradle build files, including how to automatically build alternative versions of your app – perfect if you want to release a free and a paid version. Once we’ve covered thesebuild variantsandproduct flavors, I’ll also share how to save yourself a tonne of time, by using Gradle tasks and the Gradle wrapper to automate additional parts of the Android build process.

By the end of this article, you’ll have a deeper understanding of what Gradle is, how it works, and how you can use it to customize Android’s build process, to better suit your specific app.

Android studio - gradle tasks

So, what exactly is Gradle?

Whenever you write code, there’s almost always a series of commands you’ll need to run, in order to convert that raw code into a usable format. When it’s time to create an executable file, youcouldrun each of these commands manually – or you could let a build automation tool do the hard work for you!

Build automation tools can save you a significant amount of time and effort by performing all the tasks associated with building a binary, including fetching your project’s dependencies, running automated tests, and packaging your code.

gradle tasks in android studio

Since 2013, Google have promotedGradleas the preferred build automation tool for Android developers. This open source build automation system and dependency manager can perform all the work required to convert your code into an executable file, so you don’t have to manually run the same series of commands every single time you want to build your Android app.

How does Gradle work?

Gradle manages the Android build process via several build files, which are generated automatically every time you create a new Android Studio project.

Instead of Java, XML or Kotlin, these Gradle build files use the Groovy-based domain-specific language (DSL). If you’re not familiar with Groovy, then we’ll be taking a line-by-line look at each of these Gradle build files, so by the end of this article you’ll be comfortable with reading and writing simple Groovy code.

Android studio - local libraries in gradle tasks

Gradle aims to make your life easier, by providing a set of default settings that you can often use with minimum manual configuration – when you’re ready to build your project, simply press Android Studio’s “Run” button and Gradle will start the build process for you.

Despite Gradle’s “convention over configuration” approach, if its default settings don’t quite meet your needs, then you can customize, configure and extend the build process, and even tweak the Gradle settings to perform very specific tasks.

android studio - building projects with gradle wrapper

Since the Gradle scripts are contained in their own files, you can modify your application’s build process at any time, without having to touch your application’s source code. In this tutorial, we’ll be modifying the build process using flavors, build variants and a custom Gradle task – all withoutevertouching our application code.

Exploring the Gradle build files

Every time you create a project, Android Studio will generate the same collection of Gradle build files. Even if you import an existing project into Android Studio, it’llstillcreate these exact same Gradle files, and add them to your project.

To start to get a better understanding of Gradle and the Groovy syntax, let’s take a line-by-line look at each of Android’s Gradle build files.

1. settings.gradle

The settings.gradle file is where you’ll define all of your application’s modules by name, using the “include” keyword. For example, if you had a project consisting of an “app” and a “secondModule,” then your settings.gradle file would look something like this:

Depending on the size of your project, this file may be considerably longer.

During the build process, Gradle will examine the contents of your project’s settings.gradle file and identify all the modules that it needs to include in the build process.

2. build.gradle (project level)

The project-level build.gradle file is located in your project’s root directory and contains settings that will be applied toallyour modules (also referred to as “projects” by Gradle).

You should use this file to define any plugins, repositories, dependencies, and configuration options that apply to every module throughout your Android project. Note that if you define any Gradle tasks within the project-level build.gradle file, then it’s still possible to override or extend these tasks for individual modules, by editing their correspondingmodule-levelbuild.gradle file.

A typical project-level build.gradle file will look something like this:

This project-level build.gradle file is divided into the following blocks:

3. build.gradle (module level)

This is the module-level build.gradle file, which is present in every module throughout your project. If your Android project consists of multiple modules, then it’ll also consist of multiple module-level build.gradle files.

Each module-level build.gradle file contains your project’s package name, version name and version code, plus the minimum and target SDK for this particular module.

A module-level build.gradle file can also have its own unique set of build instructions and dependencies. For example, if you’re creating an application with a Wear OS component, then your Android Studio project will consist of a separate smartphone/tablet module and a Wear module – since they’re targeting entirely different devices, these modules with have drastically different dependencies!

A basic module-level build.gradle file will typically look something like this:

Let’s take a closer look at each of these sections:

Declaring your project’s dependencies: Local libraries

you may make additional functionality available to your Android projects, by adding one or more project dependencies. These dependencies can be local, or they can be stored in a remote repository.

To declare a dependency on a local JAR file, you’ll need to add that JAR to your project’s “libs” directory.

You can then modify the module-level build.gradle file to declare a dependency on this file. For example, here we’re declaring a dependency on a “mylibrary” JAR.

Alternatively, if your “libs” folder contained several JARs, then it might be easier to simply state that your project depends on all the files located within the “libs” folder, for example:

Adding a build dependency: Remote repositories

If a library is located in a remote repository, then you’ll need to complete the following steps:

Connecting to a remote repository

The first step, is telling Gradle which repository (or repositories) it needs to check, in order to retrieve all of your project’s dependencies. For example:

Here, the “jcenter()” line ensures that Gradle will check theJCenter repository, which is a free, public repository hosted at bintray.

Alternatively, if you or your organization maintain a personal repository, then you should add this repository’s URL to your dependency declaration. If the repository is password-protected, then you’ll also need to provide your login information, for example:

If a dependency is present within multiple repositories, then Gradle will select the “best” version of this dependency, based on factors such as the age of each repository and the static version.

Declaring a remote dependency

The next step is declaring the dependency in your module-level build.gradle file. You add this information to the “dependencies” block, using any of the following:

We define a remote dependency, using one of the above keywords, followed by the dependency’s group, name and version attributes, for example:

Generating multiple APKs: How to create build variants

Sometimes, you may need to create multiple versions of your application. For example, you might want to release a free version and a paid version, which includes some additional features.

This is a build task that Gradle can help you with, so let’s look at how you’d modify the build process to create multiple APKs from a single project:

Let’s break down what’s happening here:

Creating a custom Gradle task

Sometimes you may need to customize the build process, using Gradletasks.

A task is a named collection of actions that Gradle will execute as it performs a build, for example generating a Javadoc. Gradle supports plenty of tasks by default, but you can also create custom tasks, which can come in handy if you have a very specific set of build instructions in mind.

In this section, we’ll be creating a custom Gradle task that will iterate through all of our project’s build variants (paidDebug, paidRelease, freeDebug and freeRelease), create a date and time stamp, and then append this information to each generated APK.

Open your module-level build.gradle file and add the following:

Next, we need to tell Gradlewhenit should execute this task. During a build, Gradle identities everything it needs to download and all the tasks it has to execute, and arranges them in aDirected Acyclic Graph (DAG). Gradle will then execute all of these tasks, according to the order defined in its DAG.

For my app, I’m going to use the “whenReady” method, which ensures our task will be called once the DAG has been populated, and Gradle is ready to start executing its tasks.

Add the following to your module-level build.gradle file:

Let’s put our custom taskandour build variant code to the test, by building this project using a Gradle command.

Building your project with the Gradle wrapper

You issue Gradle commands using the Gradle wrapper (“gradlew”). This script is the preferred way to start a Gradle build, as it makes the execution of the build independent from your version of Gradle. This separation can be useful if you’re collaborating with others who may not necessarily have the same version of Gradle installed.

When issuing your Gradle wrapper commands, you’ll use “gradlew” for Unix-like operating systems, including macOS, and “gradlew.bat” for Windows. I have a Mac, so I’ll be using “gradlew” commands.

You can issue Gradle commands from inside Android Studio:

Android Studio should look something like this:

Gradle stores all of the generated APKs in your project’s app/build/outputs/apk directory, so navigate to this directory. The “APK” folder should contain several folders and subfolders; make sure that Gradle has generated an APK for each of your build variants, and that the correct date and time information has been added to each file.

What other Gradle tasks are available?

In addition to any custom tasks you might create, Gradle supports a list of predefined tasks out-of-the-box. If you’re curious to see exactly what tasks are available, then:

This “tasks” task will now run, and after a few moments the Terminal will display a list of all the tasks available for this project, complete with a short description of each task.

Getting more out of Gradle: Adding plugins

Gradle ships with a number of plugins pre-installed, but you can further extend Gradle by adding new plugins. These plugins make new tasks available to your Android projects, for example the Java plugin includes tasks that allow you to compile Java source code, run unit tests and create a JAR file, such as “compileJava,” “compileText,” “jar,” “javadoc,” and “clean.”

To apply a plugin, add the “apply plugin” declaration to your module-level build.gradle file, followed by the name of the plugin. For example, here we’re applying the Java plugin:

If you’re curious to see what plugins are available, then check outGradle Plugin search, which provides a comprehensive registry of Gradle plugins.

The Gradle Kotlin DSL

By default, you’ll write your Gradle build scripts using the Groovy DSL, but if you’re one of the many developers who’ve adopted Kotlin for Android development, then you may prefer to write your build scripts in Kotlin instead.

Unlike Groovy, Kotlin is a statically typed programming language, so if you make the switch then your build files will be compatible with Android Studio’s autocompletion and source code navigation features. Plus, moving from Groovy to Kotlin means you’ll be using the same programming language across your project, which can make development more straightforward – particularly if you’re not overly familiar with Groovy!

If you want to start writing your build logic in Kotlin, then you’ll need to setup theGradle Kotlin DSLand follow the instructions in themigration guide.

Wrapping up

In this article, we explored Android Studio’s build automation and dependency management tool. We examined how Gradle automates the build process out-of-the-box, and how you can modify the build process by editing your project’s Gradle build files, including creating custom Gradle tasks, and generating multiple build variants from a single project.

Have you extended Gradle to automate other parts of the Android build process? Let us know in the comments below!

Thank you for being part of our community. Read ourComment Policybefore posting.