How does Android turn your Kotlin code into an APK?
And what actually changes when you use Jetpack Compose instead of XML?
When you click Build → APK in Android Studio, your source code goes through several stages before becoming an installable APK.
⚡ How an Android App Becomes an APK — 9 Steps
1️⃣ Kotlin/Java Source Code Compilation
2️⃣ Jetpack Compose Code Transformation
3️⃣ .class Bytecode → .dex with D8/R8
4️⃣ Android Resources Compilation with AAPT2
5️⃣ AndroidManifest.xml Merging
6️⃣ APK Packaging
7️⃣ Code Shrinking & Optimization
8️⃣ APK Alignment with Zipalign
9️⃣ APK Signing 🔐
_______________________________________________________
NOW STEPS DETAILS
1️⃣ Kotlin/Java → JVM Bytecode
Your Kotlin/Java source code is first compiled into JVM .class bytecode.
class User {
fun getName(): String = "Android"
}
⬇️
Kotlin / Java
↓
.class bytecode
For Kotlin, the Kotlin compiler handles this compilation step.
2️⃣ .class → .dex
Android devices don't execute JVM .class files directly.
The D8 compiler converts the bytecode into DEX (Dalvik Executable) format.
.class
↓
D8
↓
.dex
DEX is the format used by the Android Runtime (ART).
If R8 is enabled for the release build, it can also perform shrinking, optimization, and obfuscation as part of the release build process.
3️⃣ What happens to Jetpack Compose code?
This is where Compose becomes interesting.
Consider:
@Composable
fun Greeting(name: String) {
Text("Hello $name")
}
You don't write an XML layout.
The Compose compiler/plugin transforms composable code so that it can participate in Compose's runtime and recomposition model.
Eventually, that code is compiled down through the normal Kotlin/Android compilation pipeline:
Composable Kotlin
↓
Compose compiler transformation
↓
JVM bytecode
↓
D8
↓
DEX
So Compose is not generating an XML layout behind the scenes.
4️⃣ What happens with XML layouts?
With the traditional View system:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello Android" />
XML resources are processed by AAPT2.
The XML isn't shipped simply as the original text file for Android to interpret.
AAPT2 compiles Android resources into the application's resource table and packaged resource representation.
XML / Resources
↓
AAPT2
↓
Compiled Android resources
The APK can therefore contain compiled resources, including binary XML representations for applicable XML resources.
5️⃣ Resource Processing
Things such as:
strings.xml
drawables
colors
themes
XML resources
images
are processed through the Android resource pipeline.
The resulting resources are packaged into the APK alongside your compiled code.
6️⃣ Manifest Merging
Your application may depend on many libraries.
Each library can have its own:
AndroidManifest.xml
Gradle's Android build system merges these manifests into the final application manifest.
This can include:
Activities
Services
Permissions
Providers
Metadata
Application configuration
7️⃣ Everything gets packaged
Now the build system brings the pieces together:
Kotlin / Java
↓
.class → .dex
Compose code
↓
Compose compiler → .class → .dex
Resources
↓
AAPT2 → compiled resources
Manifest
↓
Manifest merger
↓
Packaging
↓
APK
The APK is essentially a packaged application containing your compiled code, resources, manifest information, and other required files.
8️⃣ Optimization for Release Builds
For release builds, R8 can:
✅ Remove unused code
✅ Optimize bytecode
✅ Obfuscate names
✅ Reduce application size
Then zip alignment is applied as part of APK packaging/signing workflows to optimize how the packaged data is laid out.
9️⃣ APK Signing 🔐
Before distribution, the APK needs to be digitally signed.
Your signing key allows Android and distribution systems to verify the APK's authenticity and integrity.
For Play distribution, modern Android apps are commonly uploaded as AAB (Android App Bundle) rather than directly distributing one universal APK.
So what's really different between XML and Compose?
XML + Views
XML layout
↓
AAPT2
↓
Compiled resources
↓
APK
↓
View system loads/inflates layout
Jetpack Compose
Composable Kotlin
↓
Compose compiler
↓
Kotlin/JVM bytecode
↓
D8
↓
DEX
↓
Compose runtime
The important difference is that Compose defines UI through Kotlin code and the Compose runtime, whereas the traditional View system commonly defines layouts through XML resources that are inflated into View objects.
⚠️ One common misconception:
It's not accurate to say:
"Compose is faster because it doesn't parse XML."
Performance depends on much more than that.
Compose has its own runtime, composition, recomposition, layout, and drawing mechanisms. The real advantage is the declarative UI model and state-driven UI architecture, not simply eliminating XML parsing.
🧠 The simplest mental model
XML:
XML → compiled resources → View system
Compose:
Kotlin → compiled code → Compose runtime
Both ultimately become code/resources packaged into an APK and executed by Android.
That's the interesting part: whether you write XML or Kotlin, Android still has to turn your application into a form that ART can execute. 🚀
#AndroidDevelopment #Kotlin #JetpackCompose #AndroidStudio #APK #AndroidInternals #Gradle #R8 #AAPT2 #MobileDevelopment

Post a Comment
Post a Comment