Skip to main content

Overview

TechSales uses Gradle with Kotlin DSL for build configuration. The project follows modern Android build practices with centralized dependency management through version catalogs.

Project Structure

The Gradle configuration is split across multiple files:
  • build.gradle.kts - Root project configuration
  • app/build.gradle.kts - Application module configuration
  • settings.gradle.kts - Project settings and repository configuration
  • gradle/libs.versions.toml - Version catalog for centralized dependency management
  • gradle.properties - Gradle and Android build properties

Root Build Configuration

The root build.gradle.kts file contains configuration common to all sub-projects:
build.gradle.kts
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
    alias(libs.plugins.android.application) apply false
}
The apply false syntax means the plugin is declared but not applied at the root level. It will be applied in the app module.

Key Features

plugins
PluginDependenciesSpec
Declares plugins using the version catalog (libs.plugins). This approach centralizes plugin versions in libs.versions.toml.
apply
boolean
default:"true"
Set to false in root build file to declare plugins without applying them. Sub-modules can then apply the plugin without specifying versions.

Settings Configuration

The settings.gradle.kts file configures repository locations and project structure:
settings.gradle.kts
pluginManagement {
    repositories {
        google {
            content {
                includeGroupByRegex("com\\.android.*")
                includeGroupByRegex("com\\.google.*")
                includeGroupByRegex("androidx.*")
            }
        }
        mavenCentral()
        gradlePluginPortal()
    }
}
plugins {
    id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}

rootProject.name = "TechSales"
include(":app")

Plugin Management

pluginManagement.repositories
RepositoryHandler
Defines where Gradle should look for plugins. Order matters - repositories are searched sequentially.
Repository Priority:
  1. Google Maven - Filtered to only include Android, Google, and AndroidX packages
  2. Maven Central - General purpose repository
  3. Gradle Plugin Portal - Official Gradle plugins

Dependency Resolution

dependencyResolutionManagement.repositoriesMode
RepositoriesMode
Set to FAIL_ON_PROJECT_REPOS to enforce centralized repository management. Prevents modules from declaring their own repositories.
With FAIL_ON_PROJECT_REPOS enabled, you cannot add repositories in module-level build files. All repositories must be declared in settings.gradle.kts.

Project Structure

rootProject.name
String
The name of the root project, displayed in Android Studio and used in various build outputs.
include
String...
Declares which modules are part of the project. TechSales includes the :app module.

Gradle Properties

The gradle.properties file contains build-wide configuration:
gradle.properties
# JVM memory settings for Gradle daemon
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8

# Use AndroidX libraries
android.useAndroidX=true

# Enable non-transitive R classes
android.nonTransitiveRClass=true

Performance Settings

org.gradle.jvmargs
String
JVM arguments for the Gradle daemon. Allocates 2GB of heap memory and sets UTF-8 encoding.
If you experience out-of-memory errors during builds, increase the -Xmx value (e.g., -Xmx4096m for 4GB).

Android Settings

android.useAndroidX
boolean
default:"false"
Enables AndroidX libraries instead of legacy support libraries. Should always be true for modern projects.
android.nonTransitiveRClass
boolean
default:"false"
Optimizes R class generation. Each library’s R class only contains its own resources, reducing APK size.

Version Catalog

The version catalog (gradle/libs.versions.toml) centralizes dependency versions:
gradle/libs.versions.toml
[versions]
agp = "9.0.1"
junit = "4.13.2"
junitVersion = "1.1.5"
espressoCore = "3.5.1"
appcompat = "1.6.1"
material = "1.10.0"
activity = "1.8.0"
constraintlayout = "2.1.4"

[libraries]
junit = { group = "junit", name = "junit", version.ref = "junit" }
ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }

Benefits of Version Catalogs

  • Centralized Version Management - Update versions in one place
  • Type-Safe Accessors - Use libs.appcompat instead of string literals
  • IDE Support - Auto-completion and version checking
  • Consistency - Ensures all modules use the same versions
Version catalogs are accessed using the libs prefix in build files: libs.plugins.android.application, libs.appcompat, etc.

Adding Custom Repositories

To add a custom repository (e.g., for a private package):
settings.gradle.kts
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        // Add custom repository
        maven {
            url = uri("https://your-repo.example.com/maven")
            credentials {
                username = providers.gradleProperty("repoUsername").orNull
                password = providers.gradleProperty("repoPassword").orNull
            }
        }
    }
}
Never commit credentials directly. Use gradle.properties (added to .gitignore) or environment variables for sensitive data.

Gradle Wrapper

TechSales uses the Gradle Wrapper to ensure consistent builds across environments:
  • gradlew (Unix/Mac) - Wrapper script for Unix-based systems
  • gradlew.bat (Windows) - Wrapper script for Windows
  • gradle/wrapper/gradle-wrapper.properties - Wrapper configuration

Using the Wrapper

# Build the app
./gradlew build

# Install debug build
./gradlew installDebug

# Run tests
./gradlew test
Always use ./gradlew instead of gradle to ensure everyone uses the same Gradle version.

Common Tasks

Updating Gradle

# Update to latest Gradle version
./gradlew wrapper --gradle-version=8.5

Viewing Dependencies

# View all dependencies
./gradlew :app:dependencies

# View only runtime dependencies
./gradlew :app:dependencies --configuration releaseRuntimeClasspath

Cleaning Build

# Clean all build outputs
./gradlew clean

Best Practices

  1. Use Version Catalogs - Centralize dependency versions in libs.versions.toml
  2. Kotlin DSL - Prefer .kts files for type safety and IDE support
  3. Centralize Repositories - Define all repositories in settings.gradle.kts
  4. Use Gradle Wrapper - Ensures consistent builds across machines
  5. Optimize Memory - Adjust org.gradle.jvmargs based on your machine’s capacity
  6. Enable Build Cache - Add org.gradle.caching=true to gradle.properties for faster builds

Build docs developers (and LLMs) love