An overview of build Gradle files (settings.gradle/.kts, build.gradle/.kts, and gradle.properties) used in Android Studio for beginners
Build Gradle is a build tool used in Android Studio to build your Android app. It can be written either in Groovy script, or Kotlin script (KTS). KTS is newer than Groovy and eventually, it will replace Groovy.
High-level functions of Build Gradle
Reads app's build configurations/scripts (settings.gradle / settings.gradle.kts and build.gradle / build.gradle.kts)
Downloads and caches app's dependencies from repositories that you specify in settings.gradle / settings.gradle.kts
Compiles the app's source code (either Java or Kotlin) into Java Bytecode, followed by Dalvik Bytecode.
Packs the Dalvik Bytecode and resources either into the APK (Android Package) or Android App Bundle
To do all these functions above, the following Gradle build configuration/script files are needed
settings.gradle / setings.gradle.kts (root directory)
build.gradle / build.gradle.kts (root directory)
gradle. properties (root directory)
build.gradle / build.gradle.kts (module directory - e.g. app directory)
All code examples below are based on Kotlin script (KTS).
settings.gradle/settings.gradle.kts
The main purpose of settings.gradle/settings.gradle.kts is to provide the repositories which specify where to download plugins and dependencies needed for your app.
pluginManagement {
repositories {
gradlePluginPortal()
google()
mavenCentral()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven ("https://jitpack.io")
}
}
rootProject.name = "New Empty Compose App"
include ("app")
pluginManagement
It configures repositories where plugins can be resolved/downloaded from gradlePluginPortal()
, google()
and mavenCentral()
. All these are just function calls to set up the repository location.
What are plugins? plugins provide tasks/functions to build.gradle /build.gradle.kts to build your Android app
gradlePluginPortal()
set up the repository hosted at plugins.gradle.org. Kotlin Android plugin(org.jetbrains.kotlin.android
) is an example that is provided in this repository. Cagoogle()
set up the repository hosted at maven.google.com. Android application project plugin (com.andoird.application
) and Android library project plugin (com.android.library
) are 2 common plugins that are provided in this repository.mavenCentral()
set up the repository hosted at repo.maven.apache.org which is a popular repository. Most apps probably do not need this, but maybe it is a good practice to leave it here.maven()
set up the custom repository. In the above example,https://jitpack.io
is the custom repository. To add another custom repository, just callmaven()
again with your custom repository URL.
dependencyResolutionManagement
It configures repositories which your code can download and resolve libraries from. For example, your code uses certain libraries and those libraries' source code is hosted at these repositories.
What are dependencies? Dependencies are libraries that you
import
as a package in your source code.
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
tells Gradle to fail the build if there are any project-specific repositories. This is to prevent another developer who may fail to build the project if he/she doesn't have the same local repository setup correctly.-
Same as the plugins,
google()
set up the maven.google.com repository andmavenCentral()
set up repo.maven.apache.org repository. Instead of providing plugin tasks, they provide dependencies (libraries) for your code.androidx.*(Android Jetpack libraries) is an example of libraries hosted at
google()
repository. You probably can't removemavenCentral()
as it is highly coupled withgoogle()
repository.
rootProject. name
This is your root project name, which can be any name.
include()
This includes the subprojects/modules that you would like to build. Usually, the app
module is pretty common. If you have implemented local libraries, you include them here too.
You can do this
include ("app", "buildutils")
or
include ("app")
include ("buildutils")
build.gradle/build.gradle.kts(root / project)
This defines the core plugins that are used by all your modules.
plugins {
id("com.android.application") version "7.4.2" apply false
id("com.android.library") version "7.4.2" apply false
id("org.jetbrains.kotlin.android") version "1.8.10" apply false
}
In case you do not aware, the functions here are infix notation. It can be rewritten as
plugins {
id("com.android.application").version("7.4.2").apply(false)
id("com.android.library").version("7.4.2").apply(false)
id("org.jetbrains.kotlin.android").version("1.8.10").apply(false)
}
which is a lot more understandable in my opinion.
id()
- plugin unique idversion()
- plugin's version-
apply()
- apply this plugin at this project level.Usually, you do NOT apply plugins at root project level. You apply the plugins in the module level.
com.android.application
- plugin to build Android app (e.g. default app module)-
com.android.library
- plugin to build Android libraryThis can be removed if you don't build android library but no harm in keeping it here
org.jetbrains.kotlin.android
- plugin to enable Kotlin support in your project.
gradle. properties (root / project)
"gradle. properties" file is used to define properties and global variables for your Gradle build scripts. Here are some typical examples:
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
android.useAndroidX=true
kotlin.code.style=official
android.nonTransitiveRClass=true
-Xmx2048m
- sets the maximum heap size to 2048M bytes for the Java Virtual MachineDfile.encoding=UTF-8
- sets the file encoding to UTF-8android.useAndroidX=true
- uses the newer Android support library, which is AndroidXkotlin.code.style=official
- enforces the "official" Kotlin code style guidelines while compiling and formatting your Kotlin code-
android.nonTransitiveRClass=true
- tells Android build tool to generate non-transitive R classes for your project.R class contains references to all the resources (e.g. images, layouts and strings)
Transitive R class means it includes references to all resources in any libraries/modules that your code depends on.
Non-transitive R class contains only references to the resources used in your project. Thus, it reduces the app package size significantly.
build.gradle/build.gradle.kts (app module)
This is an example build.gradle/.kts in an app module which consists of plugins {}
, android {}
, and dependencies {}
blocks.
plugins {
id ("com.android.application")
id ("org.jetbrains.kotlin.android")
}
android {
namespace = "vtsen.hashnode.dev.newemptycomposeapp"
compileSdk = 33
defaultConfig {
applicationId = "vtsen.hashnode.dev.newemptycomposeapp"
minSdk = 21
targetSdk = 33
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.4.3"
}
packagingOptions {
resources {
excludes.add("/META-INF/{AL2.0,LGPL2.1}")
}
}
}
dependencies {
/*...*/
implementation("androidx.compose.material3:material3:1.1.0-alpha04")
/*...*/
}
All these blocks (e.g.
plugins {}
,android {}
,dependencies {}
, etc) are domain-specify language (DSL) implemented using trailing lambda and function literal with receiver.
plugins {} Block
Similar to the build.gradle/.kts in the root project, this applies plugins in this module. It doesn't need to explicitly call version()
because it has already been specified in the root project. apply(true)
is also not needed because by default it is true.
android {} Block
This defines the properties specific to the Android platform.
namespace
- namespace for this project, where all the generated code is based on this namespace.compileSdk
- API level is used by Gradle to compile your app(usually the same astargetSdk)
defaultConfig {} Block
This specifies the default configuration for the project.
applicationId
- Unique ID that is used to identify your app on a device or in Google Play Store.minSdk
- Minimum API Level required for the app to runtargetSdk
- API level the app is designed and tested on (usually the same ascompileSdk
)
More info on minSdk
, targetSdk
and compileSdk
can be found here - minSdk vs targetSdk vs compileSdk.
versionCode
- an integer value that represents the version of your appversionName
- string value that represents the user-visible version of your app. It can be any string but is usually based on <major>.<minor>.<point> version format. It doesn't need to match the version code.testInstrumentationRunner
- specify the library to run the instrumented testvectorDrawable
- set "useSupportLibrary = true" to enable the vector drawable support for your app
buildTypes {} Block
This allows you to define different build configurations for your app. By default, there are already release and debug build variants. You can override the default by calling the release {}
and debug {}
within this buildTypes {}
block.
When you set up a new project, here are some default override build configurations for the release build variant. Technically you don't need it, I guess it is there for your reference.
isMinifyEnabled
- when this is set to true, it enables code shrinking and obfuscation (i.e. code optimization) during the build process which reduces the app size.-
proguardFiles
- specifies ProGuard rules files to use to optimize your code during the build process."proguard-android-optimize.txt" is the default code optimization rules specifically for building the android app.
"proguard-rules. pro" is a custom ProGuard rules that you can apply.
compileOptions {} Block
This specifies options related to compiling your Java code.
sourceCompatiblity
- specifies the Java version that your code uses.targetCompatiblity
- specifies the Java runtime version that your code will be executed on.
kotlinOptions {} Block
This specifies options related to compiling your Kotlin code.
-
jvmTarget
- specifies the Java Virtual Machine (JVM) version your code will be compiled for. In short, it compiles your code to byte code that is compatible with the JVM version that you specified.
If you don't specify any compile / Kotlin options here, the default value will be used which could be different for a different version of the build Gradle plugin.
Technically, JVM is for desktop app. For Android app, the runtime is called Dalvik Virtual Machine (DVM) which has been replaced by Android Runtime (ART).
If you are curious about the Kotlin compilation process for Android app, you can read this article.
buildFeatures {} Block
This is specific to the Android build system, which allows you to enable certain features.
-
compose
- setting this true enables the Jetpack Compose, which is turned off by default.
composeOptions {} Block
This specifies options related to Jetpack Compose compilation
-
kotlinCompilerExtensionVersion
- specifies the compose compiler version
packagingOptions {} Block
This specifies certain resources to exclude from the Android package - APK or Android bundle files.
-
resources
- specifies the set of resources that should be processed during the packaging processIn the above example, it excludes the following license files:
*/META-INF/AL2.0
*/META-INF/LGPL2.1
The purpose is to reduce the Android package file size.
dependencies {} Block
This declares the dependencies/libraries that your code is needed.
-
implementation
- specifies the library version that should be included in the Android package (APK/ Android bundle).
If you have unused dependencies in your Android project, it is better to remove them. This can help reduce the size of the Android package (APK/ Android bundle) and improve build times.
Conclusion
Well, build Gradle files seems a bit complex, especially for beginners. If you dig a bit deeper, it is not hard to understand. All the build script examples are taken from this basic Jetpack Compose app template which is the cleanup version of the Empty Compose Activity for the new project generation in Android studio.
Originally published at https://vtsen.hashnode.dev.
Top comments (0)