Skip to content

Module 03: Project Structure & Gradle Build System

Objective: Gain a deep understanding of Android project file organization and the Gradle build system, and be able to independently read and modify project configuration.

Comparison with Frontend Project Structure

Let's start with a side-by-side overview to build intuition:

Frontend Project (React/Vue)         Android Project
├── package.json                 ├── build.gradle (project-level)
├── tsconfig.json                ├── settings.gradle
├── .env / .env.local            ├── gradle.properties
├── node_modules/                ├── .gradle/ (build cache)
├── public/                      ├── app/ (main module)
│   ├── index.html               │   ├── build.gradle (module-level)
│   └── favicon.ico              │   ├── src/
├── src/                         │   │   ├── main/
│   ├── main.ts                  │   │   │   ├── AndroidManifest.xml
│   ├── App.tsx                  │   │   │   ├── java/ (source code)
│   ├── components/              │   │   │   ├── res/ (resource files)
│   ├── pages/                   │   │   │   └── assets/
│   ├── styles/                  │   │   ├── test/ (unit tests)
│   ├── utils/                   │   │   └── androidTest/ (instrumented tests)
│   └── assets/                  │   └── proguard-rules.pro
├── dist/ / build/               └── build/ (build output)
├── vite.config.ts
└── webpack.config.js

1. Directory Structure in Detail

1.1 Project Root Directory

MyApp/
├── .gradle/                  # Gradle cache (similar to node_modules/.cache)
├── .idea/                    # Android Studio config (similar to .vscode/)
├── app/                      # Main module (similar to src/ in frontend projects)
├── build/                    # Build output (similar to dist/)
├── gradle/                   # Gradle Wrapper files
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties   # ⭐ Locks the Gradle version
├── build.gradle              # Project-level build config
├── settings.gradle           # Module declarations
├── gradle.properties         # Gradle global properties
├── local.properties          # Local environment config (SDK path, not committed to Git)
├── gradlew                   # Gradle Wrapper script (Unix)
├── gradlew.bat               # Gradle Wrapper script (Windows)
└── proguard-rules.pro        # Code obfuscation rules

1.2 The app Module Directory (Key Focus)

app/
├── build.gradle              # ⭐ Module-level build config (most frequently edited)
├── proguard-rules.pro        # Obfuscation rules
└── src/
    ├── main/                 # Main source code
    │   ├── AndroidManifest.xml   # ⭐ App manifest file
    │   ├── java/                 # Java source code
    │   │   └── com/example/myapp/
    │   │       ├── MainActivity.java
    │   │       ├── model/        # Data models
    │   │       ├── network/      # Network requests
    │   │       ├── adapter/      # List adapters
    │   │       ├── fragment/     # Fragment screens
    │   │       ├── activity/     # Activity screens
    │   │       └── util/         # Utility classes
    │   ├── res/                  # ⭐ Resource files
    │   │   ├── layout/           # XML layout files (similar to HTML templates)
    │   │   ├── values/           # Strings, colors, dimensions, styles
    │   │   ├── drawable/         # Images, shapes, selectors
    │   │   ├── mipmap/           # App icons
    │   │   ├── menu/             # Menu definitions
    │   │   ├── anim/             # Animation definitions
    │   │   ├── xml/              # XML config files
    │   │   ├── raw/              # Raw resource files
    │   │   └── navigation/       # Navigation graphs (Jetpack Navigation)
    │   └── assets/               # Raw assets (not compiled, bundled as-is)
    ├── test/                     # Unit tests (run on JVM)
    │   └── java/
    └── androidTest/              # Instrumented tests (require an Android device)
        └── java/

1.3 Multi-Module Projects

Large legacy projects often have multiple modules (similar to a frontend monorepo):

MyApp/
├── settings.gradle           # Declares all modules
├── app/                      # Main app module
├── library-core/             # Core library module
├── library-network/          # Network library module
├── library-ui/               # UI component library module
└── feature-login/            # Login feature module
groovy
// settings.gradle
include ':app'
include ':library-core'
include ':library-network'
include ':library-ui'
include ':feature-login'

2. AndroidManifest.xml

This is the "ID card" and "routing table" of an Android app, similar to index.html + route configuration in a frontend project.

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

    <!-- Permission declarations (similar to browser permission requests) -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CAMERA" />

    <!-- Global app configuration -->
    <application
        android:name=".MyApplication"          <!-- Custom Application class -->
        android:icon="@mipmap/ic_launcher"     <!-- App icon -->
        android:label="@string/app_name"       <!-- App name -->
        android:theme="@style/Theme.MyApp"     <!-- Global theme -->
        android:allowBackup="true"
        android:supportsRtl="true">

        <!-- Activity declaration (similar to route registration) -->
        <activity
            android:name=".MainActivity"
            android:exported="true">           <!-- Allow external launch -->
            <intent-filter>
                <!-- Mark as launcher entry point (similar to the homepage) -->
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- Other Activities -->
        <activity android:name=".LoginActivity" />
        <activity android:name=".SettingsActivity" />

        <!-- Service declaration -->
        <service android:name=".service.SyncService" />

        <!-- BroadcastReceiver declaration -->
        <receiver android:name=".receiver.NetworkReceiver" />

        <!-- ContentProvider declaration -->
        <provider
            android:name=".provider.DataProvider"
            android:authorities="com.example.myapp.provider" />

        <!-- meta-data: Pass extra configuration to components -->
        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="your_api_key" />

    </application>
</manifest>

The Four Core Components

The AndroidManifest registers the four core components, which form the backbone of an Android app:

ComponentPurposeFrontend Equivalent
ActivityA single screen/pageA route page (/home, /login)
ServiceLong-running background taskWeb Worker / Service Worker
BroadcastReceiverListens for system or app eventswindow.addEventListener
ContentProviderCross-app data sharingREST API / IndexedDB

When taking over a legacy project: Start with AndroidManifest.xml -- it tells you what screens the app has, what permissions it uses, and what background services exist.

2.2 Manifest Merger

When a project contains multiple modules or library dependencies, each may have its own AndroidManifest.xml. At build time Gradle merges them into a final manifest:

app/src/main/AndroidManifest.xml
library-core/src/main/AndroidManifest.xml
Library A's AndroidManifest.xml

Manifest Merger

app/build/intermediates/merged_manifest/...

Common merge conflicts:

ConflictCauseFix
android:allowBackup conflictDifferent values in multiple modulesOverride in app's manifest with tools:replace="android:allowBackup"
Duplicate permissionsSame permission declared by multiple librariesUsually auto-deduplicated; use tools:node="remove" if needed
android:exported conflictInconsistent export attributeExplicitly override in app's manifest
xml
<application
    android:allowBackup="false"
    tools:replace="android:allowBackup">
    <!-- Explicitly override the library's allowBackup setting -->
</application>

Debugging tip: The merged manifest is at app/build/intermediates/merged_manifest/... — check there first when issues arise.

3. Gradle Build System

3.1 What Is Gradle?

Gradle is Android's build tool, equivalent to npm + webpack/vite combined in the frontend world:

Gradle FeatureFrontend Equivalent
Dependency managementnpm install / package.json
Compiling Java codetsc (TypeScript compilation)
Packaging APKnpm run build
Running testsnpm test
Code signing(deployment pipeline)

3.2 Gradle Wrapper

properties
# gradle/wrapper/gradle-wrapper.properties
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

Similar to .nvmrc or the engines field in frontend: ensures the team uses the same Gradle version.

Important: Don't casually change the Gradle Wrapper version! Legacy projects may depend on a specific Gradle version.

3.3 settings.gradle

groovy
// settings.gradle (Groovy DSL, common in legacy projects)
pluginManagement {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}

rootProject.name = "MyApp"
include ':app'
kotlin
// settings.gradle.kts (Kotlin DSL, common in newer projects)
pluginManagement {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}

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

3.4 Project-Level build.gradle

groovy
// build.gradle (project root directory)
// Configure plugins shared by all modules here
plugins {
    id 'com.android.application' version '8.2.0' apply false
    id 'com.android.library' version '8.2.0' apply false
}

3.5 Module-Level build.gradle (Most Important!)

This is the file you'll modify most often, equivalent to a module's package.json + tsconfig.json:

groovy
// app/build.gradle
plugins {
    id 'com.android.application'
}

android {
    namespace 'com.example.myapp'
    compileSdk 34                    // Compile target API level

    defaultConfig {
        applicationId "com.example.myapp"  // App unique identifier (package name)
        minSdk 24                          // Minimum supported version
        targetSdk 34                       // Target runtime version
        versionCode 1                      // Version code (integer, used by app stores)
        versionName "1.0.0"                // Version name (string, shown to users)

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    // Build types (similar to .env.development / .env.production in frontend)
    buildTypes {
        release {
            minifyEnabled true             // Enable code obfuscation/shrinking
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
                    'proguard-rules.pro'
            signingConfig signingConfigs.debug  // Signing configuration
        }
        debug {
            minifyEnabled false
            debuggable true
            applicationIdSuffix ".debug"   // Debug package name suffix
        }
    }

    // Flavor dimensions (e.g., free vs. paid, domestic vs. international)
    flavorDimensions "version"
    productFlavors {
        free {
            dimension "version"
            applicationIdSuffix ".free"
        }
        paid {
            dimension "version"
            applicationIdSuffix ".paid"
        }
    }

    // Java compile options
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }

    // View binding (replaces findViewById)
    buildFeatures {
        viewBinding true
    }

    // Resource shrinking
    buildTypes {
        release {
            shrinkResources true
        }
    }

    // Source sets: different build types / flavors can have independent code and resources
    sourceSets {
        main {
            java.srcDirs = ['src/main/java']
            res.srcDirs = ['src/main/res']
        }
        debug {
            // src/debug/java and src/debug/res are recognized automatically
        }
    }
}

// Dependencies (similar to dependencies in package.json)
dependencies {
    // AndroidX core libraries
    implementation 'androidx.core:core-ktx:1.12.0'
    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.11.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'

    // Jetpack components
    implementation 'androidx.lifecycle:lifecycle-viewmodel:2.7.0'
    implementation 'androidx.lifecycle:lifecycle-livedata:2.7.0'
    implementation 'androidx.navigation:navigation-fragment:2.7.6'
    implementation 'androidx.navigation:navigation-ui:2.7.6'
    implementation 'androidx.room:room-runtime:2.6.1'

    // Networking
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    implementation 'com.squareup.okhttp3:okhttp:4.12.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:4.12.0'

    // Image loading
    implementation 'com.github.bumptech.glide:glide:4.16.0'

    // JSON parsing
    implementation 'com.google.code.gson:gson:2.10.1'

    // Common dependencies in legacy projects
    implementation 'com.jakewharton:butterknife:10.2.3'  // View binding (legacy)

    // Test dependencies
    testImplementation 'junit:junit:4.13.2'
    testImplementation 'org.mockito:mockito-core:5.8.0'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}

Build Variants and Source Sets

Combining buildTypes and productFlavors, Gradle generates all possible build variants:

buildTypes: debug, release
productFlavors: free, paid

Generated variants:
- freeDebug
- freeRelease
- paidDebug
- paidRelease

Each variant can have its own source directory:

app/src/
├── main/              # shared by all variants
├── debug/             # debug variant only
├── release/           # release variant only
├── free/              # free flavor only
├── paid/              # paid flavor only
├── freeDebug/         # free + debug combination only
└── paidRelease/       # paid + release combination only
java
// src/debug/java/com/example/myapp/Config.java
public class Config {
    public static final String API_BASE_URL = "https://api-staging.example.com";
}

// src/release/java/com/example/myapp/Config.java
public class Config {
    public static final String API_BASE_URL = "https://api.example.com";
}

Frontend analogy: Similar to .env.development and .env.production, but more powerful — you can replace entire classes or resource files.

3.6 Dependency Configuration Types

Gradle ConfigMeaningnpm Equivalent
implementationAvailable at compile time and runtime, not exposed to consumersdependencies
apiSame as implementation, but exposed to consumersNo direct equivalent
compileOnlyOnly available at compile timedevDependencies (approximately)
runtimeOnlyOnly available at runtimeNo direct equivalent
testImplementationOnly available for testsdevDependencies (test-related)
androidTestImplementationOnly available for instrumented testsdevDependencies (E2E tests)

3.7 Dependency Repositories

groovy
repositories {
    google()           // Google Maven repository (AndroidX, Material)
    mavenCentral()     // Maven Central (most open-source libraries)
    jcenter()          // ⚠️ Deprecated, but legacy projects may still use it
    maven { url 'https://jitpack.io' }  // JitPack (direct GitHub project references)
}

3.8 Common Gradle Commands

bash
# Clean build (similar to rm -rf dist/ node_modules/.cache)
./gradlew clean

# Build Debug APK
./gradlew assembleDebug

# Build Release APK
./gradlew assembleRelease

# Install to device
./gradlew installDebug

# Run unit tests
./gradlew test

# Run instrumented tests
./gradlew connectedAndroidTest

# List all available tasks
./gradlew tasks

# View dependency tree (similar to npm ls)
./gradlew app:dependencies

# Profile build time
./gradlew assembleDebug --profile

4. Resource System (res/)

Android's resource system is highly structured, similar to a combination of public/ + src/styles/ + src/assets/ in a frontend project.

4.1 res/ Directory Structure

res/
├── layout/               # XML layout files (UI definitions for screens/components)
│   ├── activity_main.xml
│   ├── fragment_home.xml
│   └── item_user.xml     # List item layout
├── values/               # Value resources (strings, colors, dimensions, styles)
│   ├── strings.xml       # String constants
│   ├── colors.xml        # Color definitions
│   ├── dimens.xml        # Dimension definitions
│   ├── themes.xml        # Theme definitions
│   └── styles.xml        # Style definitions
├── drawable/             # Drawable resources
│   ├── ic_home.xml       # Vector icon
│   ├── bg_button.xml     # Button background shape
│   └── selector_tab.xml  # State selector
├── mipmap-xxxhdpi/       # App icons (different resolutions)
├── menu/                 # Menu definitions
├── anim/                 # Animation definitions
├── xml/                  # XML config files
├── raw/                  # Raw resources (audio, video, etc.)
└── navigation/           # Navigation graphs

4.2 Resource References

Resources are referenced in Java code and XML via the R class:

java
// The R class is auto-generated and contains IDs for all resources
// Format: R.resourceType.resourceName

// Referencing in Java code
setContentView(R.layout.activity_main);           // Reference a layout file
String appName = getString(R.string.app_name);    // Reference a string
int color = getColor(R.color.primary);            // Reference a color
imageView.setImageResource(R.drawable.ic_home);   // Reference an image
xml
<!-- Referencing in XML -->
<TextView
    android:text="@string/hello_world"
    android:textColor="@color/primary"
    android:textSize="@dimen/text_size_large"
    android:background="@drawable/bg_button" />

R.java Generation

At build time, AAPT2 (Android Asset Packaging Tool) scans the res/ directory and generates integer IDs for each resource, aggregating them into the auto-generated R.java:

java
// Auto-generated, do not modify manually
public final class R {
    public static final class layout {
        public static final int activity_main = 0x7f030004;
    }
    public static final class id {
        public static final int tv_title = 0x7f080059;
    }
    public static final class string {
        public static final int app_name = 0x7f0b001f;
    }
    // ...
}

Frontend analogy: Similar to Webpack/Vite generating module IDs or import.meta.glob for asset files.

Common R file errors:

ErrorCauseFix
cannot find symbol class RResource compilation failed or cache issueBuild → Clean Project / Rebuild
R.id.xxx not foundWrong ID or not compiledCheck XML and re-sync
AAPT: resource not foundReferenced resource doesn't existCheck resource file names and IDs

4.3 values/strings.xml

xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">My App</string>
    <string name="hello_world">Hello, World!</string>

    <!-- String with parameters -->
    <string name="welcome_message">Welcome, %1$s! You have %2$d messages.</string>

    <!-- String array -->
    <string-array name="week_days">
        <item>Monday</item>
        <item>Tuesday</item>
        <item>Wednesday</item>
    </string-array>
</resources>
java
// Usage
String appName = getString(R.string.app_name);
String welcome = getString(R.string.welcome_message, "John", 5);
// -> "Welcome, John! You have 5 messages."

String[] days = getResources().getStringArray(R.array.week_days);

4.4 values/colors.xml

xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="primary">#FF6200EE</color>
    <color name="primary_dark">#FF3700B3</color>
    <color name="accent">#FF03DAC5</color>
    <color name="text_primary">#DE000000</color>
    <color name="text_secondary">#99000000</color>
    <color name="background">#FFFFFFFF</color>

    <!-- Color with alpha (AARRGGBB) -->
    <color name="overlay">#80000000</color>
</resources>

4.5 values/dimens.xml

xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- dp: density-independent pixels, for layout dimensions (similar to CSS rem) -->
    <dimen name="padding_small">8dp</dimen>
    <dimen name="padding_medium">16dp</dimen>
    <dimen name="padding_large">24dp</dimen>
    <dimen name="button_height">48dp</dimen>

    <!-- sp: scale-independent pixels, for font sizes (scales with system font settings) -->
    <dimen name="text_size_small">12sp</dimen>
    <dimen name="text_size_medium">16sp</dimen>
    <dimen name="text_size_large">20sp</dimen>
</resources>

Unit Reference:

Android UnitDescriptionCSS Equivalent
dp (density-independent pixel)Pixel that doesn't change with screen densityrem (approximately)
sp (scale-independent pixel)Like dp, but also follows system font size settingsrem (for fonts)
pxPhysical pixelspx (not recommended)

Rule of thumb: Use dp for layout dimensions, sp for font sizes, and never use px.

4.6 values/themes.xml

xml
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- App theme (similar to CSS :root variables + global styles) -->
    <style name="Theme.MyApp" parent="Theme.MaterialComponents.DayNight">
        <item name="colorPrimary">@color/primary</item>
        <item name="colorPrimaryDark">@color/primary_dark</item>
        <item name="colorAccent">@color/accent</item>

        <!-- Status bar color -->
        <item name="android:statusBarColor">?attr/colorPrimaryDark</item>
    </style>
</resources>

5. BuildConfig & Version Management

5.1 BuildConfig

Gradle auto-generates a BuildConfig class containing build configuration info:

java
// BuildConfig is auto-generated
public final class BuildConfig {
    public static final boolean DEBUG = true;
    public static final String APPLICATION_ID = "com.example.myapp.debug";
    public static final String BUILD_TYPE = "debug";
    public static final int VERSION_CODE = 1;
    public static final String VERSION_NAME = "1.0.0";
}

// Usage in code
if (BuildConfig.DEBUG) {
    Log.d("App", "This is a debug build");
}
String baseUrl = BuildConfig.DEBUG
    ? "https://api-staging.example.com"
    : "https://api.example.com";

5.2 Custom BuildConfig Fields

groovy
// app/build.gradle
android {
    defaultConfig {
        buildConfigField "String", "API_BASE_URL", '"https://api.example.com"'
        buildConfigField "int", "MAX_RETRY_COUNT", "3"
        buildConfigField "boolean", "ENABLE_ANALYTICS", "false"
    }

    buildTypes {
        debug {
            buildConfigField "String", "API_BASE_URL", '"https://api-staging.example.com"'
            buildConfigField "boolean", "ENABLE_ANALYTICS", "false"
        }
        release {
            buildConfigField "String", "API_BASE_URL", '"https://api.example.com"'
            buildConfigField "boolean", "ENABLE_ANALYTICS", "true"
        }
    }
}

6. Signing Configuration

Publishing to the app store requires signing:

groovy
// app/build.gradle
android {
    signingConfigs {
        release {
            storeFile file("keystore/release.jks")
            storePassword "your_store_password"
            keyAlias "your_key_alias"
            keyPassword "your_key_password"
        }
    }

    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
}

Security tip: Never commit signing files or passwords to Git. Use local.properties or environment variables to manage sensitive information.

7. ProGuard / R8 Code Obfuscation

proguard
# proguard-rules.pro

# Keep all classes that implement Serializable
-keepclassmembers class * implements java.io.Serializable { *; }

# Keep Gson model classes
-keep class com.example.myapp.model.** { *; }

# Keep Retrofit interfaces
-keep,allowobfuscation interface * {
    @retrofit2.http.* <methods>;
}

# Keep enums
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

Frontend equivalent: Terser / UglifyJS minification and obfuscation.

8. Gradle Checklist for Taking Over a Legacy Project

When opening a legacy project, check in this order:

  1. gradle-wrapper.properties: Confirm the Gradle version -- don't upgrade casually
  2. Project-level build.gradle: Confirm the Android Gradle Plugin (AGP) version
  3. Module-level build.gradle:
    • compileSdk: Compile target version
    • minSdk: Minimum supported version
    • targetSdk: Target runtime version
    • dependencies: Third-party libraries in use
  4. settings.gradle: Confirm the module structure
  5. gradle.properties: Confirm global configuration

AGP and Gradle Version Compatibility Table

AGP VersionMinimum Gradle VersionMinimum JDK
8.2.x8.217
8.1.x8.017
8.0.x8.017
7.4.x7.511
7.3.x7.411
7.2.x7.3.311
7.1.x7.211
7.0.x7.011
4.2.x6.7.18
4.1.x6.58

Common Sync Failures and Fixes

Error MessageCauseFix
Could not find com.android.tools.build:gradle:X.X.XAGP version incompatible with Gradle versionCheck the compatibility table above
Unsupported class file major version XXJDK version too lowUpgrade JDK
Could not resolve all files for configurationDependency download failedCheck network/mirror configuration
SDK location not foundSDK path not configuredCheck local.properties
Duplicate class foundDependency conflict, two libraries contain the same classUse ./gradlew app:dependencies to investigate and exclude
Manifest merger failedMulti-module manifest attribute conflictCheck app/build/intermediates/merged_manifest
AAPT2 error: check logs for detailsResource file naming or format errorCheck res/ file names and XML syntax
Method count exceeded 64KMethod count exceeds 65,536Enable multiDexEnabled true
bash
# View full dependency tree to investigate conflicts
./gradlew app:dependencies --configuration releaseRuntimeClasspath

# Show only conflicting dependencies
./gradlew app:dependencies --configuration releaseRuntimeClasspath | grep "\->" | sort | uniq

Frontend Developer Cheat Sheet

Frontend ConceptAndroid EquivalentNotes
package.jsonbuild.gradleDependencies and project config
npm installGradle SyncDownload dependencies
dependenciesimplementation 'group:artifact:version'Different dependency declaration format
.envbuildConfigField + BuildConfigEnvironment configuration
index.htmlAndroidManifest.xml + activity_main.xmlEntry point definition
Route config<activity> in AndroidManifest.xmlScreen registration
dist/build/outputs/apk/Build output
.nvmrcgradle-wrapper.propertiesTool version locking
CSS variablesvalues/colors.xml + values/dimens.xmlGlobal style variables
@media queriesResource qualifiers (values-xxhdpi/, etc.)Adapt to different screens
public/assets/Uncompiled raw resources
Tree-shakingR8 / ProGuardRemove unused code

Next Steps

Now that you understand the project structure, move on to Module 04: Activity & Fragment to learn about Android's screens and lifecycle.

A Java Android development tutorial for frontend developers