Skip to main content

Setting Up Project Configuration

1. Configuring build.gradle Files

File Location Content
build.gradle (Module: app) app/build.gradle
plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
}

android {
    namespace 'com.example.myapp'
    compileSdk 34

    defaultConfig {
        applicationId "com.example.myapp"
        minSdk 21
        targetSdk 34
        versionCode 1
        versionName "1.0"
    }

    buildTypes {
        release {
            minifyEnabled 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'
    }
}

dependencies {
    implementation 'androidx.core:core-ktx:1.12.0'
    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.10.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}
build.gradle (Project) build.gradle
buildscript {
    ext.kotlin_version = "1.9.23"
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:8.2.0'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
    }
}

Example: Adding a dependency

dependencies {
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
}

2. Setting Kotlin Version and Compiler Options

Option Values Description
kotlin_version 1.9.23 Version of Kotlin to use in the project
kotlin.compiler.languageVersion 1.9 Language version for the Kotlin compiler
kotlin.compiler.apiVersion 1.9 API version for the Kotlin compiler
kotlin.compiler.jvmTarget 17 Target JVM version for compiled bytecode

Example: Gradle Configuration

android {
    compileSdk 34

    defaultConfig {
        targetSdk 34
        minSdk 21
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }

    kotlinOptions {
        jvmTarget = "17"
        languageVersion = "1.9"
        apiVersion = "1.9"
    }
}
Note: Ensure that the kotlin_version in your build.gradle matches the version specified in your project's gradle.properties.
Warning: Using a jvmTarget lower than the required version may lead to runtime errors or missing features.

3. Configuring Android SDK Versions

Property Value Description
compileSdk 34 SDK version used to compile the app
targetSdk 34 SDK version the app is targeting
minSdk 21 Minimum SDK version the app supports

Example: build.gradle.kts (app level)

android {
    compileSdk = 34

    defaultConfig {
        applicationId = "com.example.myapp"
        minSdk = 21
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"
    }
}
Note: Ensure compileSdk and targetSdk are set to the same version for compatibility.

4. Setting Up Build Types

Build Type Description Default Properties Use Case
debug Used during development. Includes debugging symbols and enables live reload. debuggable true, minifyEnabled false Development and testing with full debugging support.
release Optimized for production. Includes code shrinking and obfuscation. debuggable false, minifyEnabled true Production deployment with optimized performance.
staging Used for internal testing before release. Similar to release but with debug support. debuggable true, minifyEnabled true Internal testing with optimized code but debug support.

Example: Configuring Build Types in build.gradle.kts

&nbsp;&nbsp;android {<br>&nbsp;&nbsp;&nbsp;&nbsp;buildTypes {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;debug {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;isDebuggable = true<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;isMinifyEnabled = false<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;release {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;isDebuggable = false<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;isMinifyEnabled = true<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;staging {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;isDebuggable = true<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;isMinifyEnabled = true<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}
Note: Build types can be customized further with buildConfigField or resValue to inject values at compile time.

5. Configuring Product Flavors

Product flavors in Android allow you to build different versions of your app with varying features, resources, or code. They are defined in the build.gradle file and enable you to maintain a single codebase while creating multiple variants of your app.

Flavor Name Description Use Case
free Basic version with limited features Free app distribution with ads or basic functionality
pro Full-featured version without ads Premium app with enhanced features and no advertisements

Example: Defining Product Flavors

android {
    compileSdk 34

    defaultConfig {
        applicationId "com.example.myapp"
        minSdk 21
        targetSdk 34
        versionCode 1
        versionName "1.0"
    }

    flavorDimensions "version"
    productFlavors {
        free {
            dimension "version"
            applicationIdSuffix ".free"
            versionNameSuffix "-free"
        }
        pro {
            dimension "version"
            applicationIdSuffix ".pro"
            versionNameSuffix "-pro"
        }
    }
}

Example: Adding Flavor-Specific Resources

Flavor-specific resources are placed in src/free/res/ or src/pro/res/. For example, you can have different icons or strings per flavor.

src/free/res/values/strings.xml
<resources>
    <string name="app_name">MyApp Free</string>
</resources>

src/pro/res/values/strings.xml
<resources>
    <string name="app_name">MyApp Pro</string>
</resources>
Note: Flavor dimensions must be defined before any product flavor. Each flavor must belong to a dimension, and multiple dimensions can be used for more complex configurations.

Key Points

  • Product flavors allow building multiple app variants from a single codebase.
  • Flavors can have different resources, application IDs, and version names.
  • Use flavorDimensions to group related flavors.
  • Flavor-specific code and resources should be placed in src/<flavorName>/ directories.

6. Managing Dependencies

Dependency Version Repository Description
androidx.core:core-ktx 1.12.0 AndroidX Core Kotlin extensions for Android
androidx.lifecycle:lifecycle-runtime-ktx 2.7.0 AndroidX Kotlin extensions for Lifecycle
com.google.dagger:hilt-android 2.50 Dagger Dependency injection framework
com.squareup.retrofit2:retrofit 2.9.0 Retrofit Type-safe HTTP client for Android
com.github.bumptech.glide:glide 4.16.0 Glide Image loading and caching library

Example: Adding Dependencies to build.gradle.kts

dependencies {
    implementation("androidx.core:core-ktx:1.12.0")
    implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
    implementation("com.google.dagger:hilt-android:2.50")
    kapt("com.google.dagger:hilt-android-compiler:2.50")
    implementation("com.squareup.retrofit2:retrofit:2.9.0")
    implementation("com.github.bumptech.glide:glide:4.16.0")
}
Note: Ensure that kapt is applied for Hilt compiler in Kotlin projects.

Dependency Management Best Practices

  • Use implementation for direct dependencies
  • Use kapt for annotation processors like Hilt
  • Keep versions consistent across modules
  • Use api for dependencies that need to be exposed to consumers

7. Setting Up ProGuard Rules

Example: Basic ProGuard Configuration

-keep public class com.example.MainActivity {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclassmembers class com.example.model.** {
    <fields>;
    <methods>;
}

-keepnames class com.example.BuildConfig
Rule Description Usage
-keep Prevents class or member from being obfuscated Use to preserve public APIs
-keepclassmembers Keeps members of a class but allows the class to be obfuscated Use for internal model classes
-keepnames Prevents renaming of classes but allows obfuscation Use for BuildConfig or reflection targets
Note: ProGuard rules are applied during the build process in release builds. Debug builds typically do not use ProGuard.
Warning: Incorrect ProGuard rules can break runtime behavior or cause crashes in release builds.

ProGuard Rule Categories

  • API Preservation: Keep public APIs to prevent breaking changes
  • Internal Class Protection: Protect internal model classes and their members
  • Build Configuration: Preserve BuildConfig and reflection targets

8. Configuring Build Features

Feature Description Configuration Notes
Build Variants Define different versions of the app for various environments buildTypes and productFlavors Used for debug, release, staging builds
Build Scripts Customize build logic using Gradle scripts build.gradle.kts Supports Kotlin DSL for configuration
ProGuard/R8 Code shrinking, optimization, and obfuscation minifyEnabled Enabled by default in release builds
Instant Run Fast deployment during development enable in android Deprecated in favor of Apply Changes
Build Cache Speed up builds by caching intermediate results buildCache Available in Gradle 4.1+

Example: Build Types Configuration

android {
    buildTypes {
        debug {
            debuggable true
            applicationIdSuffix ".debug"
        }
        release {
            isMinifyEnabled = true
            proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
        }
    }
}

Example: Product Flavors

android {
    flavorDimensions "version"
    productFlavors {
        free {
            dimension "version"
            applicationIdSuffix ".free"
        }
        paid {
            dimension "version"
            applicationIdSuffix ".paid"
        }
    }
}

9. Setting Application ID and Version

Property Value Description
applicationId com.example.myapp Unique identifier for the app in the Android ecosystem
versionCode 1 Positive integer used by Google Play to determine app updates
versionName "1.0" Human-readable version string displayed to users

Example: app/build.gradle.kts

android {
    namespace = "com.example.myapp"
    compileSdk = 34

    defaultConfig {
        applicationId = "com.example.myapp"
        minSdk = 21
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }
}
Note: The versionCode must be incremented with each release, while versionName can be updated to reflect user-facing version information.

10. Configuring Signing Configs

Property Description Values
storeFile Path to the keystore file file('path/to/keystore.jks')
storePassword Password to access the keystore 'your-store-password'
keyAlias Alias of the key in the keystore 'your-key-alias'
keyPassword Password for the specific key 'your-key-password'

Example: Signing Config in build.gradle.kts

android {
    signingConfigs {
        create("release") {
            storeFile = file("path/to/keystore.jks")
            storePassword = "your-store-password"
            keyAlias = "your-key-alias"
            keyPassword = "your-key-password"
        }
    }
}
Note: Store passwords and key aliases should be kept secure and not hardcoded in version-controlled files.

11. Using Version Catalogs

Version catalogs in Android projects help manage dependency versions centrally, improving maintainability and consistency across the project.

Property Value Description
libs.versions 1.0.0 Version catalog version used in the project
libs.kotlin.stdlib 1.9.20 Kotlin standard library version
libs.androidx.core 1.10.1 AndroidX Core library version

Example: Defining a version catalog in libs.versions.toml

[versions]
kotlin = "1.9.20"
androidx-core = "1.10.1"

[libraries]
kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlin" }
androidx-core = { group = "androidx.core", name = "core", version.ref = "androidx-core" }

[bundles]
kotlin = [ "kotlin-stdlib" ]
androidx = [ "androidx-core" ]

Example: Using version catalog in build.gradle.kts

plugins {
    id("com.android.application") version "8.2.0"
    id("org.jetbrains.kotlin.android") version "1.9.20"
}

dependencies {
    implementation(libs.kotlin.stdlib)
    implementation(libs.androidx.core)
}
Note: Version catalogs are supported starting from Gradle 8.0 and Android Gradle Plugin 8.0.

12. Configuring Compose Compiler

Option Values Notes
compose.compiler androidx.compose.compiler:compiler Gradle plugin for Jetpack Compose compiler
kotlinOptions androidx.compose.compiler:compiler Used in build.gradle.kts to configure Compose compiler options

Example: Configuring Compose Compiler in build.gradle.kts

android {
    compileSdk = 34

    defaultConfig {
        applicationId = "com.example.myapp"
        minSdk = 21
        targetSdk = 34
    }

    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = "1.8"
    }

    buildFeatures {
        compose = true
    }

    composeOptions {
        kotlinCompilerExtensionVersion = "1.5.1"
    }
}
Note: Ensure that the kotlinCompilerExtensionVersion matches the version of Compose you are using.
Warning: Using an outdated version of the Compose compiler can lead to build failures or runtime issues.

Was this article helpful?