- Gradle for Android
- Kevin Pelgrims
- 1133字
- 2021-07-16 13:41:21
Customizing the build
There are a lot of ways to customize the build process, and when you are editing the build files in Android Studio, it is recommended to always sync the project with the Gradle files, no matter what you are customizing. This becomes especially important when you start adding dependencies or BuildConfig
fields, which we will talk about soon.
Android Studio will show a message in the editor as soon as you edit settings.gradle
or build.gradle
, and it is possible to trigger the sync at all times by navigating to Tools | Android | Sync Project with Gradle Files or the corresponding button in the toolbar.

Under the hood, the Android Studio Sync actually runs the generateDebugSources
task to generate all the necessary classes, based on the configuration in the build files.
Manipulating manifest entries
We already saw that it is possible to configure applicationId
, minSdkVersion
, targetSdkVersion
, versionCode
, and versionName
directly from the build files, instead of in the manifest file. There are a few more properties that you can manipulate:
testApplicationId
is the application ID for the instrument test APKtestInstrumentationRunner
is the name of the JUnit test runner to be used for running your test (see Chapter 6, Running Tests)signingConfig
(see Chapter 4, Creating Build Variants)proguardFile
andproguardFiles
(see Chapter 9, Advanced Build Customization)
Inside Android Studio
Instead of manually making changes in the build files, you can also change the basic settings in the Project Structure dialog in Android Studio. You can open the dialog from the File menu, and it enables you to edit project-wide settings and settings per module. For every Android module, you can change the standard Android plugin properties and all the manifest properties. In the following screenshot, you can see the properties for the release version of the app module in the Project Structure dialog:

Be aware that if you make any changes in the Project Structure dialog, Android Studio will write the changes to the Gradle build configuration file.
BuildConfig and resources
Ever since SDK tools revision 17, the build tools generate a class called BuildConfig
, which contains a DEBUG
constant that is set according to the build type. This is useful if you have code that you only want to run when debugging, such as logging. It is possible through Gradle to extend that file so that you can have constants that contain different values in debug and release.
These constants are useful for toggling features or setting server URLs, for example:
android { buildTypes { debug { buildConfigField "String", "API_URL", "\"http://test.example.com/api\"" buildConfigField "boolean", "LOG_HTTP_CALLS", "true" } release { buildConfigField "String", "API_URL", "\"http://example.com/api\"" buildConfigField "boolean", "LOG_HTTP_CALLS", "false" } } }
The escaped double quotes around the string value are necessary for it to be generated as an actual string. After adding the buildConfigField
lines, it is possible to use BuildConfig.API_URL
and BuildConfig.LOG_HTTP
in your actual Java code.
More recently, the Android Tools team has also added the possibility to configure resources in a similar manner:
android { buildTypes { debug { resValue "string", "app_name", "Example DEBUG" } release { resValue "string", "app_name", "Example" } } }
The escaped double quotes are not necessary here, because resource values are always wrapped with value=""
by default.
Project-wide settings
If you have multiple Android modules in one project, it can be useful to apply settings to all of them without manually changing the build file for every module. We already saw how the allprojects
block is used in the generated top-level build file to define repositories, and you can use the same strategy to apply Android-specific settings as well:
allprojects { apply plugin: 'com.android.application' android { compileSdkVersion 22 buildToolsVersion "22.0.1" } }
This will only work if all your modules are Android app projects though, because you need to apply the Android plugin to get access to the Android-specific settings. A better way to achieve this behavior is to define the values in the top-level build file, and then apply them in the modules. It is possible in Gradle to add extra ad hoc properties on the Project
object. This means that any build.gradle
file can define extra properties, and this happens in an ext
block.
You can add an ext
block with custom properties to the top-level build file:
ext { compileSdkVersion = 22 buildToolsVersion = "22.0.1" }
This makes it possible to use the properties in module-level build files using rootProject
:
android { compileSdkVersion rootProject.ext.compileSdkVersion buildToolsVersion rootProject.ext.buildToolsVersion }
Project properties
The ext
block in the previous example is a way of defining extra properties. You can use properties to customize a build process on the fly, and we will make use of them when we start writing custom tasks in Chapter 7, Creating Tasks and Plugins. There are several ways to define properties, but we will only look at the three most used ones:
- The
ext
block - The
gradle.properties
file - The
-P
command-line parameter
Here is an example build.gradle
file that incorporates those three ways of adding extra properties:
ext { local = 'Hello from build.gradle' } task printProperties << { println local // Local extra property println propertiesFile // Property from file if (project.hasProperty('cmd')) { println cmd // Command line property } }
This is the accompanying gradle.properties
file (in the same folder):
propertiesFile = Hello from gradle.properties
Note
In the example, we create a new task. We will look at tasks and explain the syntax in Chapter 7, Creating Tasks and Plugins.
If you run the printProperties
task with a command-line parameter, the output will look like this:
$ gradlew printProperties -Pcmd='Hello from the command line' :printProperties Hello from build.gradle Hello from gradle.properties Hello from the command line
Thanks to custom properties, changing the configuration of a build is as easy as changing a single property, or even just adding a command-line parameter.
Note
It is possible to define properties, both in the top-level build file and in the module build files. If a module defines a property that already exists in the top-level file, it will simply override it.
Default tasks
If you run Gradle without specifying a task, it runs the help
task, which prints some information on how to work with Gradle. This happens because the help task is set as the default task. It is possible to override the default task and have a very common task, or even multiple tasks, run every time you execute Gradle without explicitly specifying the task.
To specify default tasks, add this line to the top-level build.gradle
file:
defaultTasks 'clean', 'assembleDebug'
Now, when you run the Gradle wrapper without any parameters, it will run clean
and assembleDebug
. It is easy to see which tasks are set as default by running the tasks
task and filtering the output.
$ gradlew tasks | grep "Default tasks" Default tasks: clean, assembleDebug