What happens when you tap an app icon
Trace the half second between your finger and the first frame — the launcher, the message it sends, the system service that answers it, the pre-warmed process your app is torn from, and the first line of your own code.
The half second nobody explains
You tap an icon. Something happens. An app is there.
Between those two moments, five different pieces of software talk to each other, a new is created out of thin air, and your own finally gets a turn. It takes roughly a third of a second on a decent phone.
Most people building apps never learn what happens in that gap. Then something goes wrong — the app opens to a white flash, or crashes before showing anything, or takes four seconds to start — and they have no map of the territory. This lesson is the map.
Think about a bakery that never starts from scratch.
In the corner sits a big bowl of starter dough: already mixed, already proved, kept alive all day. When an order comes in, the baker does not reach for flour and water. They tear off a lump of the starter and shape it into your loaf. Your loaf is brand new, but it did not begin at the beginning — it began already half made.
Android does exactly this. A process called the is created when the phone boots, and it sits in memory with all the common Android machinery already loaded. When you tap an icon, Android tears off a copy of the Zygote and turns that copy into your app.
That is why apps open in a blink instead of a minute. Almost none of the work is done when you tap. It was done hours ago, at breakfast time, when the phone booted.
Step 1 — the launcher is just an app
The home screen is not part of Android in some special magical way. It is an app, called the , written by whoever made your phone. Pixel Launcher, One UI Home, Nova — they are all ordinary apps that happen to draw a grid of icons.
Which means the launcher has exactly the same powers you do. It cannot reach into another app and start it. Nobody can. All it can do is ask Android on your behalf.
Step 2 — your tap becomes a message
The launcher turns your tap into an : a small message describing something you want done.
An intent is not a command. It is closer to a note pushed under a door. It says what should happen and leaves who does it to Android. The one the launcher sends looks like this in plain English:
Start whichever screen in
com.nativeworks.diceduelsays it is the main launcher screen.
Intents are used all over Android — sharing a photo, opening a link, picking a contact. Every one of them is the same idea: describe the job, let the system find the worker.
Step 3 — the Activity Manager checks the register
The intent goes to the , a system service that has been running since boot. It keeps the register of every app installed on the phone: what each one is called, which screens it has, and which of those screens are allowed to be started from outside.
Here is the part that surprises people. The Activity Manager has never read your Kotlin. It knows nothing about your code. Everything it knows came from one small XML file that was read once, at install time: your . Lesson 2.3 pulls that file apart line by line.
If your app is not in the register, or the screen is not marked as startable from outside, nothing happens. That is the source of one of the most confusing beginner errors, and it is in the Error Doctor below.
Step 4 — a process appears
Assuming the app is not already running, there is nowhere for it to run yet. Android forks the — makes a copy of that pre-warmed process — and hands the copy to your app.
Your app now has:
- its own private slice of memory that no other app can read,
- its own copy of , the Android Runtime, ready to execute code,
- a , the single line of work that will draw every frame and handle every tap from now on.
That last one matters more than it sounds. There is one main thread. If you ever do something slow on it, the screen freezes, because the thread that was going to draw the next frame is busy doing your slow thing instead. Part 4 spends real time on this.
Step 5 — Android draws a window before your app exists
This is the bit nobody tells beginners, and it explains a flash of colour you have seen a thousand times.
Android does not wait for your app to be ready before putting something on screen. The moment the process is created, it throws up an empty window filled with a single colour, taken from your app's theme. Then it waits for you to fill it.
1<style
2 name="Theme.DiceDuel"
3 parent="android:Theme.Material.Light.NoActionBar">
4 <item name="android:windowBackground">#FFF7F4FF</item>
5</style>That windowBackground colour is what you see in the split second before the app draws. Pick a colour close to your real screen and the launch looks smooth. Leave it white while your app is dark and every launch begins with a flash in the face. Lesson 2.4 covers where that file lives and why.
Step 6 — your code finally runs
Now, at last, something you wrote executes. In order:
- Android creates an
Applicationobject — one per app, the first thing alive. - Android creates the named in the manifest.
- It calls that Activity's
onCreatefunction.
Which is this, the whole file, from the Dice Duel app you will build in Part 5:
1package com.nativeworks.diceduel
2
3import android.os.Bundle
4import androidx.activity.ComponentActivity
5import androidx.activity.compose.setContent
6
7class MainActivity : ComponentActivity() {
8 override fun onCreate(state: Bundle?) {
9 super.onCreate(state)
10 setContent {
11 DiceDuelTheme {
12 GameScreen()
13 }
14 }
15 }
16}Nine meaningful lines. onCreate is the door Android knocks on, and setContent { } says "everything inside this window is described by now — here is the screen." Part 3 is entirely about what goes inside that block.
Step 7 — the first frame
Compose works out what to draw, hands a list of shapes and text to the graphics system, and the screen finally shows your app. The blank window is replaced. The launch is over.
Cold, warm and hot
Not every launch does all seven steps. Android keeps your process alive in the background as long as it can afford to, so tapping the icon again often skips most of the work.
| Kind | What already exists | Roughly how long |
|---|---|---|
| Cold | Nothing. New process, new Activity. | 400 ms – 2 s |
| Warm | The process is alive; the screen was destroyed. | 100 – 400 ms |
| Hot | Everything is alive, just hidden. | Under 100 ms |
A is the one worth measuring, because it is the one a user gets after a reboot, or after Android has quietly killed your app to free memory. You will meet that second case again in Lesson 2.2 under a blunter name: .
Want to force a cold start to see the difference? Fully close the app from the recents view first. Tapping Home only hides it — the process usually stays alive, and you get a hot start.
You are going to watch your own app start, in your own log.
- Open Pocket Studio and tap Projects. Open the app you built in Part 0.
- Tap Editor, then open the file tree and tap
app/src/main/AndroidManifest.xml. - Find the
<intent-filter>block near the bottom. Those four lines are what the launcher searched the register for. Leave them alone — just look. - Open
MainActivity.ktfrom the same tree. - Add one line directly under
super.onCreate(state):println("HELLO from onCreate") - Tap Build, then press Run.
- When the app opens, open Logcat in the Build tab and search for
HELLO. That line was printed at step 6 of this lesson. - Press Home, then tap your app's icon again. No new
HELLOappears — the Activity was never destroyed, soonCreatenever ran again. That is a hot start. - Now swipe the app away in the recents view and tap the icon once more.
HELLOappears again. That is a cold start.
app/src/main/AndroidManifest.xml and check there is an <activity android:name=".MainActivity" ... > inside <application>. The leading dot means "in this app's package" — a missing dot is the usual cause.<intent-filter> containing the action android.intent.action.MAIN and the category android.intent.category.LAUNCHER. Exactly one activity should have it.onCreate was called — and then your own code threw an error inside it. The launch got as far as step 6 and fell over.INSTALL_FAILED_ line above this one — that is the real error.- The is an ordinary app. It cannot start your app; it can only send an asking Android to.
- The answers that intent using a register built from your at install time. It has never seen your Kotlin.
- Your is forked from the , which is why launching is fast.
- Android shows an empty window in your theme's colour immediately, then calls
onCreate, andsetContent { }hands the window to . - A does all of this; a hot start does almost none of it.
- Next: what an actually is, and the six moments Android tells your screen about — including the one that quietly destroys it every time you rotate the phone.