Android Plug-in for Gradle

The Android build system consists of an Android plugin for Gradle. Gradle is an advanced build toolkit that manages dependencies and allows you to define custom build logic. Android Studio uses a Gradle wrapper to fully integrate the Android plugin for Gradle. The Android plugin for Gradle also runs independent of Android Studio. This means that you can build your Android apps from which Android Studio and from the command line on your machine or on machines where Android Studio is not installed (such as continuous integration servers).

The output of the build is the same whether you are building a project from the command line, on a remote machine, or using Android Studio.

Build configuration

The build configuration for your project is defined inside build.gradle files, which are plain text files that use the syntax and options from Gradle and the Android plugin to configure the following aspects of your build:

  • Build variants. The build system can generate multiple APKs with different product and build configurations for the same module. This is useful when you want to build different versions of your application without having to create a separate projects or modules for each version.
  • Dependencies. The build system manages project dependencies and supports dependencies from your local filesystem and from remote repositories. This prevents you from having to search, download, and copy binary packages for your dependencies into your project directory.
  • Manifest entries. The build system enables you to specify values for some elements of the manifest file in the build variant configuration. These build values override the existing values in the manifest file. This is useful if you want to generate multiple APKs for your modules where each of the apk files has a different application name, minimum SDK version, or target SDK version. When multiple manifests are present, manifest settings are merged in priority of buildType and productFlavor, /main manifest, and the library manifests.
  • Signing. The build system enables you to specify signing settings in the build configuration, and it can sign your APKs during the build process.
  • ProGuard. The build system enables you to specify a different ProGuard rules file for each build variant. The build system can run ProGuard to obfuscate your classes during the build process.
  • Testing. For most templates, the build system creates a test directory, androidTest and generates a test APK from the test sources in your project, so you do not have to create a separate test project. The build system can also run your tests during the build process.

Gradle build files use Domain Specific Language (DSL) to describe and manipulate the build logic through Groovy syntax. Groovy is a dynamic language that you can use to define custom build logic and to interact with the Android-specific elements provided by the Android plugin for Gradle.

Build by convention

The Android Studio build system assumes sensible defaults for the project structure and other build options. If your project adheres to these conventions, your Gradle build files are very simple. When some of these conventions do not apply to your project, the flexibility of the build system allows you to configure almost every aspect of the build process. For example, if you need to replace the default source folders in your module directories, you can configure a new directory structure in the module's build file.

Projects and modules build settings

A project in Android Studio represents the top-level Android development structure. Android Studio projects contain project files and one or more application modules. A module is a component of your app that you can build, test, or debug independently. Modules contain the source code and resources for your apps. Android Studio projects can contain several kinds of modules:

  • Android application modules contain application (mobile, TV, Wear, Glass) code and may depend on library modules, although many Android apps consists of only one application module. The build system generates APK packages for application modules.
  • Android library modules contain reusable Android-specific code and resources. The build system generates an AAR (Android ARchive) package for library modules.
  • App Engine modules contain code and resources for App Engine integration.
  • Java library modules contain reusable code. The build system generates a JAR package for Java library modules.

Android Studio projects contain a top-level project Gradle build file that allows you to add the configuration options common to all application modules in the project. Each application module also has its own build.gradle file for build settings specific to that module.

Project Build File

By default, the project-level Gradle file uses buildscript to define the Gradle repositories and dependencies. This allows different projects to use different Gradle versions. Supported repositories include JCenter, Maven Central, or Ivy. This example declares that the build script uses the JCenter repository and a classpath dependency artifact that contains the Android plugin for Gradle version 1.0.1.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.0.1'

        // NOTE: Do not place your application dependencies here: they belong
        // in the individual module build.gradle files
    }
}

allprojects {
   repositories {
       jcenter()
   }
}

Note: The SDK location for the Android Studio project is defined in the local.properties file in the sdk.dir setting or through an ANDROID_HOME environment variable.

Module Build File

The application module Gradle build file allows you to configure module build settings, including overriding the src/main manifest settings and setting custom packaging options.

  • android settings
    • compileSdkVersion
    • buildToolsVersion
  • defaultConfig and productFlavors
    • manifest properties such as applicationId, minSdkVersion, targetSdkVersion, and test information
  • buildTypes
    • build properties such as debuggable, ProGuard enabling, debug signing, version name suffix and testinformation
  • dependencies

This example applies the Android plugin, uses the default configuration to override several manifest properties, creates two build types: release and debug, and declares several dependencies.

apply plugin: 'com.android.application'

android {
    compileSdkVersion 20
    buildToolsVersion "20.0.0"

    defaultConfig {
        applicationId "com.mycompany.myapplication"
        minSdkVersion 13
        targetSdkVersion 20
        versionCode 1
        versionName "1.0"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
         debug {
            debuggable true
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:20.0.0'
    compile project(path: ':app2, configuration: 'android-endpoints')
}

Note: You can inject custom build logic for property values defined by a function that gets called by the property, for example:

def computeVersionName() {
  ...
}

android {
    defaultConfig {
        versionName computeVersionName()
        ...
    }
}

Dependencies

The Android Studio build system manages project dependencies and supports module dependencies, local binary dependencies, and remote binary dependencies.

Module Dependencies

An application module can include in its build file a list of other modules it depends on. When you build this module, the build system assembles and includes the required modules.

Local Dependencies

If you have binary archives in your local filesystem that a module depends on, such as JAR files, you can declare these dependencies in the build file for that module.

Remote Dependencies

When some of your dependencies are available in a remote repository, you do not have to download them and copy them into your project. The Android Studio build system supports remote dependencies from repositories, such as Maven, and dependency managers, such as Ivy.

Many popular software libraries and tools are available in public Maven repositories. For these dependencies you only have to specify their Maven coordinates, which uniquely identify each element in a remote repository. The format for Maven coordinates used in the build system is group:name:version. For example, the Maven coordinates for version 16.0.1 of the Google Guava libraries are com.google.guava:guava:16.0.1.

The Maven Central Repository is widely used to distribute many libraries and tools.

Build tasks

The Android Studio build system defines a hierarchical set of build tasks: the top-level or anchor tasks invoke dependent tasks to produce their collective build outcomes. The top-level build tasks are:

assemble

Builds the project output.

check

Runs checks and tests.

build

Runs both assemble and check.

clean

Performs the clean.

The Android plugin provides additional tasks for connectedCheck and deviceCheck for checks run on connected, emulated, and remote devices. Gradle tasks can be viewed by clicking the Gradle tab in the right margin.

Figure 1: Gradle tab

Running a top-level task, runs all the dependent tasks. For example, the assemble task has dependent tasks for assembleDebug and assembleRelease to make the debug and release APKs. The assemble task depends on these tasks so calling it builds both APKs. These tasks can also be called independently to build the debug or release APK separately.

You can view the list of available tasks and invoke any task from Android Studio and from the command line, as described in Building and Running from Android Studio and Build the project from the command line.

The Gradle wrapper

Android Studio projects contain the Gradle wrapper, which consists of:

  • A JAR file
  • A properties file
  • A shell script for Windows platforms
  • A shell script for Mac and Linux platforms

Note: You should submit all of these files to your source control system.

Using the Gradle wrapper (instead of the local Gradle installation) ensures that you always run the version of Gradle defined in the local.properties file. To configure your project to use a newer version of Gradle, edit the properties file and specify the new version there.

Android Studio reads the properties file from the Gradle wrapper directory inside your project and runs the wrapper from this directory, so you can seamlessly work with multiple projects that require different versions of Gradle.

Note: Android Studio does not use the shell scripts, so any changes you make to them won't work when building from the IDE. You should define your custom logic inside Gradle build files instead.

You can run the shell scripts to build your project from the command line on your development machine and on other machines where Android Studio is not installed.

Caution: When you create a project, only use the Gradle wrapper scripts and JAR from a trusted source, such as those generated by Android Studio.

Build variants

Each version of your app is represented in the build system by a build variant. Build variants are combinations of product flavors and build types. Product flavors represent product build versions of an app, such as free and paid. Build types represent the build packaging versions generated for each app package, such as debug and release. The build system generates APKs for each combination of product flavor and build type.

By default, Android Studio defines default configuration settings, defaultConfig in the build.gradle file, and two build types (debug and release). This creates two build variants, debug and release, and the build system generates an APK for each variant.

Adding two product flavors, demo and full along with the default build types debug and release generates four build variants, each with its own customized configuration:

  • demoDebug
  • demoRelease
  • fullDebug
  • fullRelease
Resources are merged across the multiple Android application sources:
  • Build variants based on the buildType, and productFlavor build settings
  • The main sourceSet, generally located in src/main/res
  • Library Project dependencies, which contribute resources through the res entry in their aar bundle.

The priority of the merge order from lowest to highest is libraries/dependencies -> main src -> productFlavor -> buildType.

Some projects have complex combinations of features along more than one dimension, but they still represent the same app. For example, in addition to having a demo and a full version of the app, some games may contain binaries specific to a particular CPU/ABI. The flexibility of the build system makes it possible to generate the following build variants for such a project:

  • x86-demoDebug
  • x86-demoRelease
  • x86-fullDebug
  • x86-fullRelease
  • arm-demoDebug
  • arm-demoRelease
  • arm-fullDebug
  • arm-fullRelease
  • mips-demoDebug
  • mips-demoRelease
  • mips-fullDebug
  • mips-fullRelease

This project would consist of two build types (debug and release) and two dimensions of product flavors, one for app type (demo or full) and one for CPU/ABI (x86, ARM, or MIPS).

Source directories

To build each version of your app, the build system combines source code and resources from:

  • src/main/ - the main source directory (the default configuration common to all variants)
  • src/<buildType>/ - the source directory
  • src/<productFlavor>/ - the source directory

Note: The build type and product flavor source directories are optional, as Android Studio does not create these directories for you. You should create these directories as you add build types and product flavors to the build configuration files. The build system does not use these directories if they are not present.

For projects that do not define any flavors, the build system uses the defaultConfig settings, the main app directory and the default build type directories. For example, to generate the default debug and release build variants in projects with no product flavors, the build system uses:

  • src/main/ (default configuration)
  • src/release/ (build type)
  • src/debug/ (build type)

For projects that define a set of product flavors, the build system merges the build type, product flavor and main source directories. For example, to generate the full-debug build variant, the build system merges the build type, product flavor and main directories:

  • src/main/ (default configuration)
  • src/debug/ (build type)
  • src/full/ (flavor)

For projects that use flavor dimensions, the build system merges one flavor source directory per dimension. For example, to generate the arm-demo-release build variant, the build system merges:

  • src/main/ (default configuration)
  • src/release/ (build type)
  • src/demo/ (flavor - app type dimension)
  • src/arm/ (flavor - ABI dimension)

The source code from these directories is used together to generate the output for a build variant. You can have classes with the same name in different directories as long as those directories are not used together in the same variant.

The build system also merges all the manifests into a single manifest, so each build variant can define different components or permissions in the final manifest. The manifest merge priority from lowest to highest is libraries/dependencies -> main src -> productFlavor -> buildType.

The build system merges all the resources from the all the source directories. If different folders contain resources with the same name for a build variant, the priority order is the following: build type resources override those from the product flavor, which override the resources in the main source directory, which override those in any libraries.

Note: Build variants enable you to reuse common activities, application logic, and resources across different versions of your app.