A newly created Android Studio project will consist of approximately 80 files automatically generated by Android Studio. When you click on the Run button, Android Studio uses a build system called Gradle to generate additional files, compile the source code, resolve library dependencies, and create the installable application package. After the build is completed, the project folder will contain approximately 700 files.
This chapter explains how the Gradle build system determines which libraries to include in the build process and how you can use this system to add library dependencies to your projects.
Library and Plugin Dependencies
In the earlier chapter titled Android Architecture Overview, we talked briefly about the Java API Framework and the libraries that it contains. When Gradle is building a project, it needs to know which libraries are required to complete the build and their respective version numbers. For example, a project might depend on version 2.6.0 of the Room Database runtime library (androidx.room:room-runtime). Unfortunately, when we write Room Database code in our project, Gradle does not automatically add the corresponding library dependency to the build configuration. Instead, we must add this ourselves via Gradle build files and the version catalog.
Project Gradle Build File
Every Android Studio has a project-level Gradle file that you can find by navigating to Gradle Scripts -> build. gradle.kts (<Project name>) in the Project tool window. The primary purpose of this file is to define the plugins that do the work of building the entire project and will typically read as follows:
plugins {
alias(libs.plugins.androidApplication) apply false
alias(libs.plugins.jetbrainsKotlinAndroid) apply false
}
Code language: Gradle (gradle)
In practice, changes to this file are only necessary on rare occasions.
Module Gradle Build Files
An Android Studio project will consist of one or more modules, each with its own build configuration and library dependencies. A new project will contain a single module, the gradle build file for which will be listed in the Gradle Scripts folder as build.gradle.kts (Module: app) and will, in part, read as follows:
plugins {
alias(libs.plugins.androidApplication)
alias(libs.plugins.jetbrainsKotlinAndroid)
}
android {
.
.
}
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.material)
implementation(libs.androidx.activity)
implementation(libs.androidx.constraintlayout)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
}
Code language: Gradle (gradle)
dependencies { implementation(libs.androidx.core.ktx) implementation(libs.androidx.appcompat) implementation(libs.material) implementation(libs.androidx.activity) implementation(libs.androidx.constraintlayout) testImplementation(libs.junit) androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) }
The plugins section once again contains the plugins needed to build the project and, in most cases, will mirror those declared in the project-level build file. When a module needs plugins not required by other modules, they are declared here.
The dependencies section contains a list of the libraries on which the module depends and which must be resolved for a successful build.
Version Catalog File
Earlier, we mentioned that in addition the library names, dependencies must also include library version numbers. You will have noticed, however, that none of the configuration files reviewed so far include version information. This is where the version catalog file comes in. The version catalog can be found in a file named libs. versions.toml located in the Project tool window’s Gradle Scripts folder. An example version catalog file is listed below:
[versions]
agp = "8.3.0-rc01"
kotlin = "1.9.0"
coreKtx = "1.12.0"
junit = "4.13.2"
junitVersion = "1.1.5"
espressoCore = "3.5.1"
appcompat = "1.6.1"
material = "1.11.0"
activity = "1.8.0"
constraintlayout = "2.1.4"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
[plugins]
androidApplication = { id = "com.android.application", version.ref = "agp"}
.
.
Code language: Gradle (gradle)
The catalog is divided into sections labeled [versions], [libraries], and [plugins]. To help understand how the catalog works, we will use the material library as an example. In the [libraries] section, the material library is declared as follows:
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
Code language: Gradle (gradle)
The group entry above tells us the actual name of the Material library in the Java API framework is com.google. android.material, while the versions.ref assignment declares how the library will be referenced in the [versions] catalog section. The declaration is assigned to a value named “material” which is the name by which the library will be referenced in the module-level build files.
Referring to the [versions] section, we find that the library has been assigned version 1.11.0:
material = "1.11.0"
Code language: Gradle (gradle)
Finally, the library is declared in the dependencies section of the module-level build file as follows:
dependencies {
.
.
implementation(libs.material)
.
.
}
Code language: Gradle (gradle)
Note that the syntax for referencing the library in the build file is to prefix the name used in [libraries] catalog entry with “libs.”. Although we have focused on a library for this example, the syntax is the same for plugins.
Adding Dependencies
You will need to add dependencies to several projects in this book, and in each case, we will step you through the process. As a final example in this chapter, we will demonstrate adding the Room Database runtime library dependency to our earlier hypothetical project. First, we must add the following entry to the [libraries] section of the libs.versions.toml version catalog file:
[libraries]
.
.
androidx-roomruntime = { group = "androidx.room:room-runtime", name = "room-runtime", version.ref = "roomruntiume" }
Code language: Gradle (gradle)
Next, the version number is added to the [versions] catalog section:
[versions]
.
.
roomruntiume = "2.6.0"
Code language: Gradle (gradle)
Finally, the library is added to the dependencies section of the module-level gradle build file:
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.material)
implementation(libs.androidx.activity)
implementation(libs.androidx.constraintlayout)
implementation(libs.androidx.roomruntime)
.
.
}
Code language: Gradle (gradle)
Library Updates
While declaring library and plugin dependencies is primarily a manual task, one thing that Android Studio will do for you is let you know when a more recent library version is available. It does this by highlighting the version number while you are editing the catalog file. Hovering the mouse pointer over the highlighted number will display the panel shown in Figure 1-1, providing the option to change to the latest version:
Summary
Android Studio projects are built using the Gradle build system in a process involving several steps. One of these steps is to resolve and include any required libraries for the project to compile successfully. While a newly created project will include the basic libraries and plugins necessary for a simple app, more complex projects will have additional dependencies. These dependencies are declared in the module-level Gradle build files. To provide version consistency across project modules and a single location to add new libraries or update version numbers, Gradle uses a version catalog file. As your code uses more libraries and plugins, you must edit the build and catalog files to add these dependencies.
4