Skip to content
beginner Phase 2 · Android Fundamentals

Project Structure

Navigate Android project directories: manifests, java/kotlin sources, res, gradle files.

35m
0 problems
Topic Progress 0%

Project Directories

Project Directory Structure

An Android project follows a standardized directory layout:

MyApp/
├── app/
│   ├── src/
│   │   ├── main/
│   │   │   ├── java/com/example/myapp/    # Kotlin/Java source
│   │   │   ├── res/                         # Resources
│   │   │   │   ├── layout/                  # XML layouts
│   │   │   │   ├── values/                  # Strings, colors, styles
│   │   │   │   ├── drawable/                # Images and shapes
│   │   │   │   ├── mipmap/                  # App icons
│   │   │   │   └── xml/                     # Other XML configs
│   │   │   └── AndroidManifest.xml          # App manifest
│   │   ├── debug/                           # Debug-specific sources
│   │   └── release/                         # Release-specific sources
│   ├── build.gradle.kts                     # Module build config
│   └── proguard-rules.pro                   # ProGuard/R8 rules
├── build.gradle.kts                         # Project-level build config
├── settings.gradle.kts                      # Project settings
├── gradle.properties                        # Gradle properties
└── gradle/
    └── wrapper/
        ├── gradle-wrapper.jar
        └── gradle-wrapper.properties        # Gradle version

Source Sets

The src/ directory contains source sets — collections of source files and resources grouped by build variant:

  • main: Default source set used by all build types
  • debug: Debug-only code (e.g., Stetho initialization)
  • release: Release-only code (e.g., ProGuard configuration)
  • androidTest: Instrumentation tests running on devices
  • test: Unit tests running on JVM
// src/debug/java/com/example/myapp/DebugInitializer.kt
// Only included in debug builds
object DebugInitializer {
    fun init() {
        // Enable leak detection, logging, etc.
    }
}

Package Structure Convention

Organize code by feature, not by layer:

com.example.myapp/
├── data/
│   ├── remote/
│   ├── local/
│   └── repository/
├── domain/
│   ├── model/
│   └── usecase/
├── ui/
│   ├── home/
│   ├── detail/
│   └── settings/
└── util/

This scales better than organizing by type (Activity/, Fragment/, Adapter/) because related files live together. When you add a feature, you create one directory instead of scattering files across five.

Gradle Configuration

Gradle Configuration

Project-Level vs Module-Level

The project-level build.gradle.kts configures plugins and repositories shared across all modules:

// build.gradle.kts (project)
plugins {
    id("com.android.application") version "8.2.0" apply false
    id("org.jetbrains.kotlin.android") version "1.9.20" apply false
}

The module-level build.gradle.kts configures the specific app module:

// app/build.gradle.kts
plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    kotlin("kapt")
}

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

    defaultConfig {
        applicationId = "com.example.myapp"
        minSdk = 24
        targetSdk = 35
        versionCode = 1
        versionName = "1.0"
    }

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

    flavorDimensions += "environment"
    productFlavors {
        create("dev") {
            dimension = "environment"
            applicationIdSuffix = ".dev"
        }
        create("staging") {
            dimension = "environment"
            applicationIdSuffix = ".staging"
        }
        create("production") {
            dimension = "environment"
        }
    }

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

    kotlinOptions {
        jvmTarget = "17"
    }

    buildFeatures {
        viewBinding = true
    }
}

Build Variants

Build variants combine a build type (debug/release) with a product flavor. For three flavors and two build types, you get six variants: devDebug, devRelease, stagingDebug, etc.

Dependency Management

dependencies {
    implementation("androidx.core:core-ktx:1.12.0")
    implementation("androidx.appcompat:appcompat:1.6.1")
    implementation("androidx.constraintlayout:constraintlayout:2.1.4")
    implementation("com.google.android.material:material:1.11.0")
    implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0")
    implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.7.0")
    implementation("androidx.room:room-runtime:2.6.1")
    implementation("androidx.room:room-ktx:2.6.1")
    kapt("androidx.room:room-compiler:2.6.1")
    testImplementation("junit:junit:4.13.2")
    androidTestImplementation("androidx.test.ext:junit:1.1.5")
}

Dependency configurations:

  • implementation — Not exposed to dependent modules (faster builds)
  • api — Exposed to dependent modules (use sparingly)
  • compileOnly — Available at compile time only
  • runtimeOnly — Available at runtime only
  • kapt/ksp — Annotation processing

Manifest and Resources

AndroidManifest.xml

The manifest declares your app's components, permissions, and configuration:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CAMERA" />

    <application
        android:name=".MyApplication"
        android:allowBackup="false"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.MyApp">

        <activity
            android:name=".ui.MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity android:name=".ui.DetailActivity" />

        <service
            android:name=".service.SyncService"
            android:exported="false" />
    </application>
</manifest>

Resource Directories

res/
├── layout/              # UI layouts
├── values/              # Default values
│   ├── strings.xml
│   ├── colors.xml
│   ├── dimens.xml
│   └── styles.xml
├── values-night/        # Dark theme overrides
├── values-sw600dp/      # Tablet overrides
├── drawable/            # Vector drawables, shapes
├── mipmap-xxxhdpi/      # App icons (high density)
├── xml/                 # Preference screens, backup rules
├── raw/                 # Raw files (audio, JSON)
└── navigation/          # Navigation graph

Resource Qualifiers

Qualifiers let you provide alternative resources for different configurations:

Qualifier Example Description
values-sw600dp values-sw600dp/ Tablets (7" and larger)
values-night values-night/ Dark theme
layout-land layout-land/ Landscape orientation
drawable-hdpi drawable-hdpi/ High density screens
values-fr values-fr/ French locale

The system selects the best-matching resource at runtime based on device configuration. This is how Android handles responsive design across screen sizes, orientations, languages, and themes without writing conditional code.

Quiz

1. What is the purpose of the settings.gradle.kts file?

Question 1 options

2. What does isMinifyEnabled do in a release build type?

Question 2 options

3. What is the difference between implementation and api dependency configurations?

Question 3 options

4. Why should you organize code by feature rather than by type?

Question 4 options

Flashcards

Question

What is the difference between project-level and module-level build.gradle.kts?

Answer

Project-level configures plugins and repositories shared across all modules. Module-level configures SDK versions, dependencies, and build types for a specific module.

Question

What does the applicationId do in defaultConfig?

Answer

It uniquely identifies your app on the device and Play Store. It can differ from your package name and supports suffixes per build variant (e.g., .debug).

Question

What are the standard source sets in an Android module?

Answer

main (default), debug, release, androidTest (instrumentation tests), and test (unit tests). Each can have its own sources and resources.

Question

What is the purpose of proguard-rules.pro?

Answer

It contains rules for R8/ProGuard code shrinking, obfuscation, and optimization during release builds. Rules specify which classes to keep or remove.

Revision Notes

Key Takeaways

  • 1. Organize code by feature, not by type, for better scalability
  • 2. Project-level build.gradle.kts configures plugins; module-level configures the app
  • 3. isMinifyEnabled enables R8 shrinking and obfuscation for release builds
  • 4. Resource qualifiers provide automatic configuration-based resource selection
  • 5. implementation hides dependencies from consumers; api exposes them

Interview Tips

  • Explain the difference between applicationId and package name
  • Know how build variants work (flavor x build type combinations)
  • Understand why feature-based package structure scales better
  • Be ready to discuss dependency configurations and when to use each

Cheat Sheet

Project Structure Cheat Sheet

Key Files:

  • settings.gradle.kts — declares included modules
  • build.gradle.kts (project) — plugins, shared config
  • build.gradle.kts (module) — SDK versions, dependencies
  • AndroidManifest.xml — app components, permissions

Build Types:

  • debug — unoptimized, debuggable, .debug suffix
  • release — minified, obfuscated, R8 enabled

Dependency Configs:

  • implementation — internal, fast builds
  • api — transitive, use sparingly
  • compileOnly — compile time only
  • kapt/ksp — annotation processing

Resource Qualifiers:

  • values-night — dark theme
  • values-sw600dp — tablet
  • layout-land — landscape
  • drawable-hdpi — screen density