Warm Start: essens, varmstart och optimering i Android

Författare: IT Sectr Publicerad: 2026-03-31 Lästid: 8 min

Warm Start är ett startscenario för en Android-app där appens process redan finns i minnet (till exempel efter minimering), men Activity har förstörts av systemet för att spara resurser. Application.onCreate har redan körts, klasser har laddats, men UI skapas på nytt. Enligt Google, 2024 tar Warm Start 200 till 800 ms och utgör cirka 40% av alla starter på enheter med 4 GB RAM.

Huvudpunkter

  • Warm Start — start av app med befintlig process men utan Activity i minnet
  • Skillnad från Cold Start: Application.onCreate körs inte, klasser är redan laddade
  • Tid Warm Start är 200–800 ms jämfört med 1–5 sekunder för Cold Start
  • Scenarier: återgång till appen efter flera timmar, borttagning av Activity av OOM-killer
  • Optimering fokuserar på att bevara Activity-tillståndet och cachning av data

Vad är Warm Start

Warm Start (varmstart) är ett tillstånd mellan Cold Start och Hot Start: appens process finns i minnet (ibland i Linux bakgrundscache), men Activity är inte aktiv och kommer att skapas på nytt. Android-systemet vid RAM-brist kan ta bort Activity från stacken och låta processen vara vid liv. När användaren återvänder till appen börjar Warm Start: en ny instans av Activity skapas, livscykelmetoderna onCreate → onStart → onResume körs, men Application.onCreate och klassladdning hoppas över.

Orsaker till Warm Start

Android-systemet beslutar om borttagning av Activity baserat på processprioritet (importance rank). En Activity i bakgrunden (nivå PROCESS_STATE_IMPORTANT_FOREGROUND eller PROCESS_STATE_TOP_SLEEPING) kan förstöras 5–30 minuter efter app-minimering, beroende på tillgängligt RAM. På enheter med 3 GB RAM kan Activity tas bort efter 10 minuter, på enheter med 8 GB — efter flera timmar. Viktigt: vid Warm Start anropas onSaveInstanceState före förstörelse av Activity och utvecklaren kan spara UI-tillståndet.

Användaruppfattning

Användaren ser ingen skillnad mellan Warm och Cold Start — han trycker bara på appikonen och väntar. Men vid Warm Start kan en vit skärm (blank window) visas om appen inte har ställt in ett eget tema för startfönstret. Google rekommenderar att ställa in ett anpassat tema i manifestet (Theme.AppCompat.Light eller Theme.Material3.DayNight) för start-Activity för att undvika flimmer av vit/svart skärm vid Warm Start. På Android 12+ döljer SplashScreen API också denna effekt.

Warm Start vs Cold Start vs Hot Start

Att förstå skillnaden mellan de tre starttyperna är nödvändigt för att välja rätt profilerings- och optimeringsstrategi. Varje typ har sin egen varaktighet, sina egna flaskhalsar och sina egna mätverktyg.

KriteriumCold StartWarm StartHot Start
ProcessSkapas på nyttFinns i minnetFinns i minnet
Application.onCreateKörsKörs inteKörs inte
ActivitySkapas från börjanSkapas från börjanÅterställs från stacken
Tid1–5 sekunder200–800 ms< 200 ms
onCreate ActivityFullständigFullständig (med restore)Hoppas över

I praktiken utgör Warm Start 30% till 60% av alla appstarter, beroende på användarens vanor och enhetens RAM-mängd. Användare som håller många appar öppna (multitasker) stöter oftare på Warm Start. För sociala nätverk och meddelandetjänster är Warm Start det vanligaste scenariot eftersom appen alltid är i bakgrunden. För bankappar dominerar däremot Cold Start (tvångsrengöring av processen av säkerhetsskäl).

Faser av varmstart

Warm Start består av tre faser, som var och en kan mätas och optimeras. Till skillnad från Cold Start finns det ingen fork-fas och klassladdning, men det finns en återställningsfas (restore) som kan vara kostsam.

Fas 1: Startfönster (window background)

Systemet kontrollerar om appen har ett tema för startfönstret. Om inget tema har ställts in visas en vit (eller svart, beroende på system) skärm. Om ett tema har ställts in visas bakgrunden från temat. Denna fas tar 10–30 ms, men är visuellt märkbar om temat inte matchar appens verkliga UI. Använd Theme.Material3.DayNight med anpassad windowBackground vars färg matchar den första skärmens bakgrund — detta skapar en effekt av omedelbar laddning.

Fas 2: Skapa Activity (återställning)

Systemet anropar onCreate med Bundle savedInstanceState som sparades i onSaveInstanceState före förstörelse av Activity. Om appen sparade tillståndet korrekt (fälttext, scrollposition, ViewModel-data) sker återställningen snabbt. Om inte — börjar Activity från en tom sida och användaren ser en loader tills data har laddats. Nyckelpunkt: ViewModel-objekt överlever Warm Start endast om processen inte förstördes — vid Warm Start förblir ViewModel i minnet.

Fas 3: Första bildrutan (TTFD)

Efter onCreate körs onStart → onResume och systemet anropar första renderingen. TTFD (Time To First Draw) för Warm Start bör vara mindre än 300 ms på en medelstor enhet. Om den första skärmen innehåller en komplex RecyclerView med tunga Views eller laddar bilder via nätverket kan TTFD överskrida tröskeln. Använd Placeholder och Shimmer för smidig laddning av innehåll efter den första bildrutan.

Hur man mäter Warm Start

Att mäta Warm Start är mer komplicerat än Cold Start eftersom du måste simulera tillståndet «processen lever, Activity förstörd». Standardkommandot ADB med flaggan -S är inte lämpligt — det dödar processen. För Warm Start använd andra metoder.

ADB shell am start utan -S

Starta först appen via adb shell monkey eller tryck på ikonen, minimera den sedan (adb shell input keyevent 3 keyevent HOME). Vänta 5–10 sekunder så att systemet kan ta bort Activity och kör adb shell am start -W (utan -S). Kommandot returnerar starttiden som blir kortare än Cold Start. För reproducerbarhet använd ett skript: starta → vänta → home → vänta → starta.

bash
# Simulering av Warm Start via ADB
$ adb shell am start -W \
    com.example.app/.MainActivity

# Utdata (Warm Start):
# ThisTime: 412 ms
# TotalTime: 412 ms
# WaitTime: 423 ms

Macrobenchmark för Warm Start

Biblioteket androidx.benchmark.macro stöder mätning av Warm Start. För detta i testet ställ in startupMode = StartupMode.WARM — biblioteket startar appen, minimerar den, väntar (konfigurerbar fördröjning) och mäter sedan omstarten. Macrobenchmark gör 10–20 körningar och beräknar percentiler. I CI/CD kan du ställa in en tröskel: om P50 Warm Start överstiger 600 ms — testet misslyckas. Detta gör det möjligt att spåra regressioner vid varje commit.

Firebase Performance Monitoring

Firebase skiljer automatiskt mellan Cold och Warm Start baserat på tiden sedan appen senast stängdes. Om appen har öppnats under de senaste 30 minuterna klassificerar Firebase starten som Warm. I Firebase-konsolen ser du separata diagram för varje starttyp, vilket gör att du kan utvärdera effektiviteten av optimeringar. Efter implementering av tillståndslagring i ViewModel kan du till exempel se en minskning av Warm Start med upp till 30%.

Optimera Warm Start

Optimering av Warm Start fokuserar på två riktningar: att påskynda Activity.onCreate och korrekt återställning av tillstånd. Eftersom Application.onCreate och klassladdning redan har utförts är den främsta flaskhalsen UI-koden på den första skärmen.

Asynkron tillståndsåterställning

Om det sparade tillståndet (savedInstanceState) innehåller data som måste deserialiseras (Bitmap, String, JSON), gör detta i en bakgrundstråd. Istället för att läsa direkt från Bundle i onCreate, starta en coroutine och visa en shimmer-skärm. I praktiken tar deserialisering av Bundle på en medelstor enhet 20–100 ms — verkar lite, men för Warm Start är detta 10–50% av den totala tiden. Använd Saved State Module från Jetpack-biblioteket som automatiskt sparar och återställer ViewModel-tillståndet i Bundle eller databas.

Optimering av setContentView

Expandering av XML-layout (layout inflation) är ett av de dyraste stegen i Warm Start. Om den första skärmen använder en komplex CoordinatorLayout med AppBar, CollapsingToolbar, NestedScrollView och tre RecyclerView kan inflationstiden nå 300 ms. Lösningar: använd ConstraintLayout för platt hierarki, tillämpa ViewStub för sektioner som är osynliga vid start (bottom sheet, dialog), aktivera asynkron expandering för tunga fragment via AsyncLayoutInflater. I Jetpack Compose behövs ingen inflation, men kompilering av Compose-trädet vid Warm Start kan ta liknande tid.

Cachning av data

Vid Warm Start kan data som appen laddade i föregående session redan finnas i cachen: Room-databas, SharedPreferences, in-memory cache i ViewModel. Om din första skärm visar en lista från servern, kontrollera cachen vid start och uppdatera data i bakgrunden. Använd strategin cache-then-network: visa först cachad data (omedelbart), uppdatera sedan från servern (asynkront). Detta minskar den upplevda tiden för Warm Start till 100–200 ms.

kotlin
// ViewModel med cachning för Warm Start
class FeedViewModel : ViewModel() {
    private val cache = MutableStateFlow<List<Item>>(emptyList())

    init {
        // Cache först, sedan nätverk
        viewModelScope.launch {
            cache.emit(db.getItems()) // Warm Start: data redan i databasen
            cache.emit(api.fetchItems()) // Bakgrundsuppdatering
        }
    }
}

Bevara tillstånd vid Warm Start

Korrekt tillståndslagring är nyckelfaktorn som skiljer en bra Warm Start från en dålig. Användaren förväntar sig att återvända till appen och se samma sak som han lämnade — inklusive scrollposition, text i fält, valda flikar.

onSaveInstanceState

Systemet anropar onSaveInstanceState vid förstörelse av Activity, men INNAN processen kan dödas. I Bundle sparas endast enkla data (String, Int, Parcelable, Serializable). För komplexa data använd SavedStateHandle i ViewModel — det sparar och återställer automatiskt fält vid Warm Start. Till skillnad från onSaveInstanceState fungerar SavedStateHandle även om processen överlevde Warm Start (ViewModel förstörs inte). Exempel: för text i EditText använd SavedStateHandle.getLiveData(“text”) — texten sparas och återställs automatiskt.

ViewModel och Warm Start

Om processen inte dödades vid Warm Start, förblir ViewModel i minnet och onCleared anropas inte. Detta innebär att all data som laddades i föregående session är omedelbart tillgänglig. Men om processen dödades (enheten i deep sleep längre än 30 minuter) förstörs ViewModel och skapas på nytt med SavedStateHandle. För korrekt ViewModel-funktion vid Warm Start använd SavedStateHandle med fält som måste återställas i alla scenarier. Skillnad: ViewModel med @HiltViewModel stöder SavedStateHandle automatiskt.

MekanismProcessen leverProcessen dödad
ViewModelData i minnetFörstörd, skapas på nytt
SavedStateHandleData i minnetÅterställs från Bundle
onSaveInstanceStateAnropas vid borttagning av ActivityAnropas inte
Room DBCache tillgängligCache tillgänglig (disk)

Bevara scroll för RecyclerView

Ett av de vanligaste problemen med Warm Start — förlust av scrollposition. Användaren scrollade flödet till det 50:e elementet, minimerade appen, kom tillbaka — och ser början av listan. Lösning: spara layoutManager.onSaveInstanceState (sparar position och offset för första synliga elementet) och återställ det i onRestoreInstanceState. Du kan också spara den senaste synliga positionen i SharedPreferences med en datum/tid-nyckel för att snabbt återställa positionen vid Warm Start.

kotlin
// Bevara scrollposition för RecyclerView
override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putParcelable(
        "rv_state", binding.recyclerView
            .layoutManager?.onSaveInstanceState()
    )
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    savedInstanceState?.getParcelable<Parcelable>("rv_state")
        ?.let { binding.recyclerView.layoutManager?.onRestoreInstanceState(it) }
}

Kodexempel för Warm Start

Två praktiska exempel på Warm Start-optimering: användning av SavedStateHandle i ViewModel och asynkron återställning av komplex data efter start.

ViewModel med SavedStateHandle

SavedStateHandle sparar automatiskt fält i Bundle och återställer dem vid Warm Start. Användarprofilfältet (String, JSON) återställs utan extra förfrågningar till servern. Om processen dödades laddar SavedStateHandle det senast sparade tillståndet från Bundle.

kotlin
class ProfileViewModel(
    private val savedStateHandle: SavedStateHandle
) : ViewModel() {

    val profile: StateFlow<Profile?>
        get() = savedStateHandle
            .getStateFlow("profile", null)

    fun loadProfile(id: String) {
        viewModelScope.launch {
            savedStateHandle["profile"] =
                api.getProfile(id)
        }
    }
}

// Warm Start: profile är inte null, UI utan loader
// Efter laddning: profile uppdateras i SavedStateHandle

AsyncLayoutInflater för tung skärm

Om den första skärmen innehåller en komplex layout (karta, gradient, flera listor), använd AsyncLayoutInflater för att expandera tunga element i bakgrunden. Medan layouten expanderas, visa en placeholder med shimmer-effekt. Detta är särskilt viktigt för Warm Start, där varje millisekund räknas. AsyncLayoutInflater arbetar i bakgrundstråden och levererar den färdiga Vyn via callback till huvudtråden.

kotlin
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Placeholder-layout för omedelbar rendering
        setContentView(R.layout.placeholder_shimmer)

        // Asynkron laddning av tung layout
        AsyncLayoutInflater(this).inflate(
            R.layout.activity_main_complex,
            findViewById(R.id.container)
        ) { view, resId, parent ->
            parent?.removeAllViews()
            parent?.addView(view)
        }
    }
}

Vanliga frågor

Kan Warm Start övergå till Cold Start?

Ja, om systemet vid Warm Start-tillfället beslutar att döda appens process (till exempel för att frigöra minne för en annan app), blir starten en Cold Start från början. Detta händer på enheter med 2–3 GB RAM när flera appar körs samtidigt. I praktiken är Warm Start endast garanterad inom 10–20 minuter efter minimering på medelklassenheter.

Behålls ViewModel vid Warm Start?

Ja, om processen inte dödades, förblir ViewModel i minnet och onCleared anropas inte. Detta är den viktigaste fördelen med Warm Start: all laddad data, nätverksförfrågningar, cache i ViewModel — omedelbart tillgänglig. Om processen dödades skapas ViewModel på nytt via ViewModelProvider.Factory eller @HiltViewModel och SavedStateHandle återställer sparade fält.

Varför kan Warm Start vara långsammare än Cold Start?

Teoretiskt är Warm Start alltid snabbare än Cold Start, men i praktiken finns det scenarier där skillnaden är minimal: om Application.onCreate är lätt (50 ms) och Activity.onCreate är tung (800 ms), då är Warm Start (800 ms) nästan lika med Cold Start (850 ms). I detta fall behöver du optimera inte Application, utan Activity.onCreate — det blir flaskhalsen för Warm Start.

Hur påverkar SplashScreen API Warm Start?

SplashScreen API på Android 12+ visar en system-splash (ikon på färgad bakgrund) omedelbart vid start — både för Cold och Warm Start. För Warm Start visas splash endast i 100–300 ms, varefter den ersätts av appens UI. SplashScreen i sig påskyndar inte starten, men maskerar tiden för Activity-skapande och förbättrar uppfattningen.

Behöver jag optimera Warm Start om Cold Start redan är snabb?

Ja, eftersom Warm Start förekommer 2–3 gånger oftare än Cold Start. Om Cold Start tar 1,2 sekunder och Warm Start 600 ms, tar 40% av starterna (Warm) fortfarande 0,6 sekunder, vilket är märkbart. Optimering av Warm Start till 200–300 ms ger användaren en känsla av omedelbar återkomst. På enheter med 6+ GB RAM kan Warm Start utgöra upp till 80% av alla starter och dess optimering blir en prioritet.

Sammanfattning

  • Warm Start — start med befintlig process, utan Activity i minnet, tid 200–800 ms
  • Huvudskillnad från Cold Start: Application.onCreate körs inte, klasser laddade
  • Tre faser av Warm Start: startfönster → skapa Activity → första bildrutan
  • Mäts via ADB utan flagga -S eller Macrobenchmark med StartupMode.WARM
  • Optimering: SavedStateHandle, AsyncLayoutInflater, cache-then-network, ConstraintLayout
  • ViewModel behålls vid Warm Start (levande process) — data omedelbart tillgänglig
  • Warm Start utgör 40–80% av alla appstarter

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också