What Gradle actually is
You press Run, something takes over for a while, and an APK appears. That something is Gradle. Here is exactly what it reads, what it fetches, what it compiles and what it packs — in plain English, with no hand-waving.
The most-asked beginner question
Ask any group of new Android developers what confuses them most and this comes back more than anything else:
What is Gradle? Why is there a file called
build.gradle.kts? Why does it keep failing at me about things I never wrote?
Here is the whole answer in one sentence, and then we will unpack every word of it.
is a program that reads your project's settings, downloads the libraries you asked for, compiles your code, and packs the result into an APK.
That is it. It is not a language, it is not part of Android, and it is not magic. It is a very literal-minded assistant that does four jobs in order.
Think about a kitchen assistant who is brilliant and completely without imagination.
You hand them two pieces of paper. One is a shopping list: flour, eggs, a particular brand of chocolate. The other is a recipe: the steps, in order, each one saying what it needs before it can start.
The assistant reads the shopping list, checks the pantry, and goes out for anything missing. Then they work through the recipe. They will not start creaming butter before the butter is soft, because the recipe says so. And they refuse — flatly — to guess. Leave one ingredient off the list and they stop and tell you, rather than improvising.
They also keep notes. Come back tomorrow and ask for the same cake and they will say "the icing is already made and nothing about it has changed, so I am not making it again."
That is Gradle. The shopping list is your dependencies. The recipe is your build files. The notes are the , and they are the reason your second build is so much faster than your first.
The four jobs, in order
Every single build you ever run does these four things.
- Read the settings. Which parts make up this project, where libraries may be downloaded from, which versions of everything.
- Fetch what is missing. Download any the project needs and does not already have, plus everything those libraries need.
- Compile. Turn your Kotlin into , turn your
resfolder into a compiled lookup table, then turn the bytecode into . - Package and sign. Zip the lot into an and sign it so a phone will accept it.
Press Run in Pocket Studio and all four happen. Nothing else is going on behind the curtain.
Gradle knows nothing about Android
This is the fact that unlocks the rest.
Out of the box, Gradle is a general-purpose build tool. It can build a website, a game, a research paper. It has never heard of an Activity, an APK or the res folder.
Android arrives as a — the , AGP for short. Adding it is what teaches Gradle every Android-specific step: merging manifests, compiling resources, making dex files, packaging APKs. This course pins AGP 8.7.3.
Two more plugins come along for the ride: the Kotlin plugin (Kotlin 2.1.0), which knows how to compile Kotlin, and the Compose plugin, which sets up the Compose compiler.
So when a build error mentions com.android.application, it is talking about AGP. When it mentions org.jetbrains.kotlin.android, it is the Kotlin plugin. Knowing which one is complaining halves the search.
The files that describe a build
A Dice Duel project has five build-related files. That is all of them.
| File | What it says |
|---|---|
settings.gradle.kts | Which modules exist, and where downloads may come from |
build.gradle.kts (root) | Which plugin versions this whole project uses |
app/build.gradle.kts | How to build the app itself |
gradle/libs.versions.toml | Every library and version, in one list |
gradle/wrapper/…properties | Which version of Gradle to use |
settings.gradle.kts — the front door
app/build.gradle.kts — the recipe
This is the file you actually edit. Trimmed here to the parts that matter for this lesson:
libs.versions.toml — every version in one place
1[versions]
2agp = "8.7.3"
3kotlin = "2.1.0"
4composeBom = "2024.12.01"
5
6[plugins]
7android-application = { id = "com.android.application",
8 version.ref = "agp" }Change a version once here and the whole project follows. That is the entire purpose of a , and it is why alias(libs.plugins.android.application) looks so indirect — the indirection is the point.
Tasks: the steps of the recipe
Gradle does not think in "builds". It thinks in — small named units of work that declare what they need and what they produce.
Real task names from a real Android build:
1:app:preBuild
2:app:processDebugManifest
3:app:mergeDebugResources
4:app:processDebugResources
5:app:compileDebugKotlin
6:app:dexBuilderDebug
7:app:packageDebug
8:app:assembleDebugRead those top to bottom and you have the four jobs again: settings, resources, compile, pack. The :app: prefix is the module name from settings.gradle.kts. Debug is the build type.
assembleDebug is the one Run uses. It does not do any work itself — it just depends on all the others, so asking for it drags the whole chain in behind it.
Gradle works out the order from the dependencies between tasks. You never write the order down.
Where the downloads come from
A is written as three parts separated by colons:
1androidx.compose.material3:material3:1.3.1
2 group name versionGradle asks google(), then mavenCentral(), until one of them has it. Then it asks that library what it needs, and fetches those too — the . Ask for Material 3 and you also get Compose Foundation, Compose UI, Compose Runtime and a dozen more, without typing a word.
You can see the whole tree:
./gradlew :app:dependenciesDice Duel declares eight lines of dependencies and resolves to about forty modules. That number matters a great deal on a phone, which is the whole of Lesson 2.6.
The wrapper and the daemon
Two pieces of Gradle machinery worth naming, because both show up in error messages.
The . Your project contains a small script, gradlew, and a properties file naming an exact Gradle version:
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zipNobody has to install Gradle. The wrapper downloads the pinned version on first use and every build after that uses it. This course pins Gradle 8.11.1 so that every reader, on every phone, runs an identical build.
The . Gradle runs inside a , and starting a JVM is slow. So Gradle leaves one running in the background after your build finishes. The next build hands its work to that already-warm process instead of starting from cold.
That is one of the main reasons your second build is dramatically faster than your first — and, on a phone, it is also a process quietly holding a couple of hundred megabytes of RAM. This line in gradle.properties is where its memory limit is set:
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8Time to look at a real build with your own eyes.
- Open Pocket Studio, tap Projects, open your Part 0 app.
- Tap Editor and open the file tree. Open
settings.gradle.kts, thenapp/build.gradle.kts, thengradle/libs.versions.toml. Read each against the walkthroughs above. - Open
gradle/wrapper/gradle-wrapper.propertiesand find8.11.1in thedistributionUrlline. That is the exact Gradle your phone is running. - Tap Build, then open the Terminal.
- Type
./gradlew tasksand run it. Scroll the list — every one of those is something Gradle can be asked to do. - Now type
./gradlew :app:assembleDebug. Watch the> Task :app:…lines scroll past. You are watching the four jobs happen in order. - Finally, run
./gradlew :app:dependenciesand scroll. Every line is a library on the phone because you asked for it, directly or indirectly.
local.properties that points at a folder no phone has.local.properties from the project root and build again. Pocket Studio supplies its own SDK location; a stale Windows path in that file overrides it and guarantees failure.gradle/libs.versions.toml first. If those are right, you are offline or the connection dropped — reconnect and build again. Gradle keeps what it already downloaded, so a retry usually only fetches the missing piece.settings.gradle.kts has google() inside pluginManagement { repositories { … } } — AGP is published there and nowhere else. Then check you are online.gradle/wrapper/gradle-wrapper.properties and set the distributionUrl to gradle-8.11.1-bin.zip. That is the version this course pins, and AGP 8.7.3 is happy with it.libs means nothing.gradle/libs.versions.toml, spelled that way, in the project root — not inside app/. Gradle only picks it up automatically at that one path.- reads your settings, fetches libraries, compiles your code and packages an . Four jobs, in that order.
- Gradle knows nothing about Android until the teaches it.
- Five files describe a build:
settings.gradle.kts, twobuild.gradle.ktsfiles,libs.versions.tomland the properties. - Work happens as like
:app:compileDebugKotlin.assembleDebugpulls the whole chain in behind it. - Libraries come from and drag their own along.
- The stays warm between builds. The pins Gradle 8.11.1 so every build is identical.
- Next: why the first build took minutes and the second took seconds — and why that matters far more on a phone than on a laptop.