Not Running — wat is het, begintoestand van de levenscyclus

Auteur: IT Sectr Gepubliceerd: 2026-03-03 Leestijd: 11 min

Not Running — de begintoestand van de levenscyclus van een mobiele app, waarin deze nog niet is gestart of al is beëindigd. Ontdek hoe het iOS- en Android-systeem deze toestand beheren, welke gebeurtenissen leiden tot de overgang van Not Running en hoe u het starten en beëindigen van de app correct verwerkt in Swift en Kotlin.

Belangrijkste punten

  • Not Running — de app is niet in het geheugen geladen en voert geen code uit, dit is het in- en uitgangspunt in de levenscyclus
  • Starten — de overgang van Not Running vindt plaats bij tikken op het pictogram, via deep link of pushmelding
  • Beëindigen — de gebruiker sluit de app met een veegbeweging, het systeem verwijdert deze bij gebrek aan geheugen of er vindt een crash plaats
  • Koude start — de app start vanaf nul, alle objecten worden opnieuw aangemaakt, de toestand wordt niet uit de cache hersteld
  • Warme start — de app was in Suspended en keert terug naar Active zonder volledige initialisatie

Not Running — wat is deze toestand

Not Running — is de basistoestand van de levenscyclus van een mobiele app, waarin deze niet in het RAM-geheugen van het apparaat is geladen en geen systeembronnen verbruikt. In iOS en Android betekent deze toestand de volledige afwezigheid van processen en threads die aan de app zijn gekoppeld. De gebruiker ziet het app-pictogram op het bureaublad, maar de app zelf is niet actief en staat niet in de recentenlijst.

Wanneer de gebruiker op het pictogram tikt, maakt het systeem een nieuw proces aan, laadt de uitvoerbare code in het geheugen en initialiseert alle benodigde gegevensstructuren. Dit proces wordt een koude start (cold start) genoemd en is het meest bronnenintensief wat betreft laadtijd.

Het systeem kan de app vanuit elke andere toestand naar Not Running verplaatsen. Als de app zich op de achtergrond (Background) of in geschorste toestand (Suspended) bevindt, heeft het besturingssysteem het recht deze te verwijderen bij gebrek aan RAM-geheugen voor prioritaire taken — bijvoorbeeld voor een actieve app op de voorgrond.

De ontwikkelaar moet er rekening mee houden dat de app op elk moment door het systeem kan worden beëindigd wanneer deze zich op de achtergrond bevindt. Dit betekent dat alle niet-opgeslagen gegevens verloren kunnen gaan. Daarom is het van cruciaal belang om de toestand op te slaan in sleutel-waarde-opslagplaatsen (UserDefaults, SharedPreferences) of in een lokale database bij overgangen van Active naar Background.

Hoe bepaalt het systeem welke app te verwijderen

iOS gebruikt prioriteiten op basis van de huidige toestand van de app: Active heeft de hoogste prioriteit, daarna Inactive, Background, Suspended en ten slotte Not Running — minimale prioriteit. Android gebruikt een vergelijkbare proceshiërarchie: het Foreground-proces heeft prioriteit OOM_ADJ = 0, Visible-proces = 100, Service-proces = 200, Background-proces = 300, Empty-proces = 400. Hoe hoger de waarde, hoe groter de kans dat het proces wordt beëindigd bij geheugengebrek.

PlatformToestandVerwijderprioriteitBeschrijving
iOSNot RunningHoogsteApp niet geladen — systeembron wordt niet verbruikt
iOSSuspendedHoogApp in geheugen, maar code wordt niet uitgevoerd — eerste doel voor verwijdering
iOSBackgroundGemiddeldApp voert achtergrondtaak uit — verwijderd na timeout
iOSActiveLaagActieve app — alleen verwijderd bij kritiek geheugengebrek
AndroidEmpty ProcessHoogsteProces zonder actieve componenten — eerst verwijderd
AndroidBackground ProcessHoogAchtergrondproces zonder zichtbare Activity
AndroidForeground ServiceLaagService met melding — zelden beëindigd
AndroidForeground ProcessMinimaalActieve Activity — als laatste beëindigd

Koude en warme start van de app

Koude start (cold start) vindt plaats wanneer de app van Not Running direct naar Active overgaat. Het systeem maakt een nieuw proces aan, laadt klassen, initialiseert statische velden, maakt de hoofdthread aan en start het UI-framework. In iOS betekent dit het aanroepen van application(_:didFinishLaunchingWithOptions:), in Android — het aanroepen van Application.onCreate() en Activity.onCreate(). De tijd van een koude start kan variëren van 200 ms tot enkele seconden, afhankelijk van de complexiteit van de app.

Warme start (warm start of hot start) — de app was in de toestand Suspended en keert terug naar werking zonder volledige herlading. Het systeem herstelt de laatste UI-stack uit het geheugen en de gebruiker gaat verder waar hij gebleven was. Een warme start is aanzienlijk sneller dan een koude start, omdat het grootste deel van de code al in het geheugen is geladen. In iOS roept een warme start application(_:didFinishLaunchingWithOptions:) niet aan, alleen applicationWillEnterForeground en applicationDidBecomeActive.

Het verschil tussen koude en warme start is kritisch voor de gebruikerservaring. Bij een koude start moet de ontwikkelaar ervoor zorgen dat het opstarten zo snel mogelijk gebeurt — luie initialisatie van modules, uitgesteld laden van zware bronnen, minimalisatie van werk in de hoofdthread bij het opstarten. Google beveelt aan een koude start van niet meer dan 500 ms, Apple — niet meer dan 400 ms voor iOS.

kotlin
// Meten van koude starttijd in Android
class App : Application() {
    private var startTime: Long = 0L

    override fun onCreate() {
        super.onCreate()
        startTime = System.currentTimeMillis()
    }

    fun getStartupTime(): Long {
        return System.currentTimeMillis() - startTime
    }
}

// Activity starten met luie initialisatie
class MainActivity : AppCompatActivity() {
    private val viewModel: MainViewModel by lazy {
        ViewModelProvider(this).get(MainViewModel::class.java)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // Alleen het absolute minimum voor het eerste frame
        setupNavigation()
    }

    override fun onPostCreate(savedInstanceState: Bundle?) {
        super.onPostCreate(savedInstanceState)
        // Zware initialisatie na rendering
        initializeHeavyModules()
    }
}

Het voorbeeld toont het meten van de koude starttijd in Android. Application.onCreate() wordt aangeroepen bij de overgang van Not Running naar Active. De tijdstempel wordt geregistreerd bij het starten van het proces. Activity gebruikt luie initialisatie via een lazy-delegate om het eerste frame niet te blokkeren. onPostCreate is de optimale plaats voor initialisatie van zware modules, omdat de UI al is weergegeven.

Not Running in iOS: Swift en AppDelegate

In iOS wordt Not Running beheerd via de delegate UIApplicationDelegate. Belangrijke methoden: application(_:didFinishLaunchingWithOptions:) wordt aangeroepen na een koude start, applicationWillTerminate(_:) wordt aangeroepen voor beëindiging van de app door de gebruiker. Het systeem kan de app echter beëindigen zonder applicationWillTerminate aan te roepen — bijvoorbeeld bij noodbeëindiging of geheugenverwijdering. iOS garandeert niet dat deze methode wordt aangeroepen, daarom moeten gegevens worden opgeslagen in applicationDidEnterBackground.

Scenario's voor overgang naar Not Running op iOS

De gebruiker kan de app handmatig beëindigen met een veegbeweging in de App Switcher. Het systeem kan de app uit het geheugen verwijderen op de achtergrond. De app kan noodgedwongen worden beëindigd (crash). In alle gevallen worden alle objecten die tijdens het opstarten zijn gemaakt, vernietigd. Toestand die niet is opgeslagen, gaat onherroepelijk verloren. In iOS 13+ wordt voor het opslaan van de toestand het gebruik van NSUserActivity of het mechanisme voor state restoration via UIApplication.stateRestorationIdentifier aanbevolen.

swift
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    // Koude start: app overgegaan van Not Running
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        // Initialisatie van minimale set services
        setupAnalytics()
        configureAppearance()
        return true
    }

    // App beëindigt — alleen handmatig sluiten
    func applicationWillTerminate(
        _ application: UIApplication
    ) {
        saveCriticalData()
    }

    // Gegevens opslaan voor naar achtergrond gaan
    func applicationDidEnterBackground(
        _ application: UIApplication
    ) {
        saveApplicationState()
    }

    private func saveCriticalData() {
        UserDefaults.standard.synchronize()
    }

    private func saveApplicationState() {
        let state = ["lastScreen": "main", "timestamp": Date()]
        try? NSKeyedArchiver.archivedData(
            withRootObject: state,
            requiringSecureCoding: true
        )
    }
}

De code toont de correcte verwerking van Not Running in iOS. applicationWillTerminate wordt alleen aangeroepen bij handmatige beëindiging door de gebruiker. Het opslaan van kritieke gegevens wordt gedupliceerd in applicationDidEnterBackground, omdat deze methode gegarandeerd wordt aangeroepen voor het naar de achtergrond gaan. State restoration maakt het mogelijk de UI-stack op te slaan voor later herstel bij een koude start.

Not Running in Android: Kotlin en proces

In Android betekent Not Running dat het proces van de app niet bestaat. Het Linux-systeem waarop Android is gebaseerd, beheert processen via het Zygote-mechanisme. Bij het starten van de app fork Zygote een nieuw proces, laadt Dalvik/ART en roept Application.onCreate() aan. In Android bestaat geen directe analoog van applicationWillTerminate — het systeem kan het proces op elk moment zonder waarschuwing beëindigen.

Levenscyclus van het Android-proces

Wanneer Activity voor het eerst wordt aangeroepen, maakt het systeem het proces, Application en Activity aan via de keten onCreate → onStart → onResume. Als de gebruiker op Back drukt, wordt Activity vernietigd (onDestroy) en kan het proces door het systeem worden beëindigd. Belangrijk verschil met iOS: in Android kan het proces blijven bestaan, zelfs zonder actieve Activities — bijvoorbeeld als er een Foreground Service draait of een actieve BroadcastReceiver is.

kotlin
// Verwerking van Not Running via SavedStateHandle in ViewModel
class MainViewModel(
    private val savedStateHandle: SavedStateHandle
) : ViewModel() {

    companion object {
        private const val KEY_LAST_SCREEN = "last_screen"
        private const val KEY_USER_DATA = "user_data"
    }

    fun saveCurrentState(screen: String, data: String) {
        savedStateHandle[KEY_LAST_SCREEN] = screen
        savedStateHandle[KEY_USER_DATA] = data
    }

    fun restoreState(): AppState? {
        val screen = savedStateHandle.get<String>(KEY_LAST_SCREEN)
        val data = savedStateHandle.get<String>(KEY_USER_DATA)
        return if (screen != null && data != null) {
            AppState(screen, data)
        } else null
    }
}

// Application — eerste callback na Not Running
class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()
        initCrashReporter()
        initDependencyInjection()
    }
}

SavedStateHandle — een component van Android Architecture Components die automatisch de toestand opslaat bij overgang naar Not Running en deze herstelt bij een koude start. ViewModel, gemaakt via ViewModelProvider, overleeft schermrotatie en vernietiging van Activity. Bij beëindiging van het proces worden gegevens uit SavedStateHandle geserialiseerd naar Bundle en opgeslagen in saved instance state.

Redenen voor overgang naar Not Running

Not Running treedt om verschillende redenen op. De gebruiker sluit de app handmatig. Het systeem verwijdert de app bij geheugengebrek. De app wordt noodgedwongen beëindigd met een uitzondering. In Android kan het systeem het proces beëindigen bij massa-update van apps of herstart van het apparaat. iOS kan de app beëindigen bij het verlopen van de tijd van een achtergrondtaak (meestal 30 seconden).

RedeniOSAndroidMogelijkheid tot voorkomen
Handmatig sluiten door gebruikerVeeg in App SwitcherVeeg uit RecentsNee — gebruikersactie
GeheugengebrekActiveren memory warningonTrimMemory / LMKGedeeltelijk — geheugenoptimalisatie
Crash van appNSException / signaalUncaughtException / ANRJa — foutafhandeling en crash-reporting
Timeout achtergrondtaak30 sec voor Background task10 min voor JobSchedulerJa — correcte taakplanning
Herstart van OSAanroep applicationWillTerminateBroadcast ACTION_SHUTDOWNNee — systeemgebeurtenis
Update van appGebeurt niet (iOS Sandbox)Proces wordt beëindigd bij APK-updateNee — systeemupdate

Hoe de overgang naar Not Running diagnosticeren

Gebruik voor iOS console-logging in applicationWillTerminate en applicationDidFinishLaunching. Voeg bij elke start een vlag toe aan UserDefaults — als de vlag bij de volgende start ontbreekt, is de app niet correct beëindigd. Gebruik in Android ActivityManager.isBackgroundRestricted() om te controleren of de app achtergrondtaken kan uitvoeren. Houd ook onTrimMemory(TRIM_MEMORY_COMPLETE) in de gaten — dit is een signaal dat het proces zal worden beëindigd.

Beste praktijken voor werken met Not Running

Eerste regel — ga er nooit van uit dat applicationWillTerminate of onDestroy zullen worden aangeroepen. Sla kritiek belangrijke gegevens op bij elke overgang van Active naar Background. Gebruik sleutel-waarde-opslagplaatsen voor eenvoudige instellingen en SQLite/Room voor gestructureerde gegevens.

Tweede regel — meet de koude starttijd en optimaliseer deze. Luie initialisatie, minimalisatie van werk in de hoofdthread, vooraf laden van bronnen, gebruik van SplashScreen API — dit alles verbetert de perceptie van de starttijd. Google beveelt aan een koude start van minder dan 200 ms voor een uitstekende UX.

Derde regel — implementeer State Restoration. Gebruik in iOS UIApplication.stateRestorationIdentifier en NSUserActivity. Gebruik in Android SavedStateHandle in ViewModel in combinatie met onSaveInstanceState. Dit stelt de gebruiker in staat verder te gaan vanaf dezelfde plek na een herstart van de app.

Vierde regel — verwerk launchOptions en Intent waarmee de app na Not Running is gestart. Deep links, pushmeldingen, universele links — ze worden allemaal doorgegeven via de startparameters. De ontwikkelaar moet deze gegevens correct extraheren en de gebruiker naar het juiste scherm leiden.

swift
// Verwerking van deep link na koude start
func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
    // Controleren of melding is aangekomen
    if let notification = launchOptions?[.remoteNotification] as? [String: Any] {
        handleNotification(notification)
    }
    // Deep link controleren
    if let url = launchOptions?[.url] as? URL {
        handleDeepLink(url)
    }
    return true
}

private func handleDeepLink(_ url: URL) {
    guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
          let screenId = components.queryItems?.first(where: { $0.name == "screen" })?.value
    else { return }
    openScreen(screenId)
}

De code toont de verwerking van startparameters bij een koude start in iOS. launchOptions bevat de gegevens waarmee het systeem de app heeft gestart. Meldingen, deep links en universele links worden via dit woordenboek doorgegeven. De ontwikkelaar moet alle mogelijke startscenario's correct verwerken om een naadloze gebruikerservaring te garanderen.

Veelgestelde vragen

Wat gebeurt er met gegevens bij overgang naar Not Running?

Gegevens die in permanente opslag zijn opgeslagen (UserDefaults, Core Data, SharedPreferences, Room), blijven behouden. Gegevens in het RAM-geheugen — variabelen, cache, ViewModel-toestand zonder SavedStateHandle — gaan onherroepelijk verloren. Daarom is het van cruciaal belang om de app-toestand op te slaan bij elke overgang naar de achtergrond.

Hoe onderscheid je een koude start van een warme start op iOS?

Bij een koude start wordt application(_:didFinishLaunchingWithOptions:) aangeroepen. Bij een warme start (terugkeer uit Suspended) wordt deze methode niet aangeroepen — alleen applicationWillEnterForeground en applicationDidBecomeActive worden geactiveerd. Als u een actie alleen bij een koude start wilt uitvoeren, stel dan een vlag in in didFinishLaunchingWithOptions.

Kan een Android-app in Not Running zijn met een actieve Service?

Ja. Foreground Service met een permanente melding voorkomt dat het proces door het systeem wordt beëindigd, zelfs als alle Activities zijn vernietigd. Background Service (startService zonder foreground) kan op elk moment door het systeem worden gestopt. Een draaiende Service betekent dat het proces bestaat en dit is niet langer Not Running.

Hoe emuleer je Not Running op de simulator?

Beëindig op de iOS-simulator de app via de App Switcher (Cmd+Shift+H twee keer, veeg omhoog). Gebruik op de Android-emulator adb shell am force-stop com.example.app of de Stop-knop in Logcat. Start de app vervolgens opnieuw — dit is een schone koude start vanuit Not Running.

Wat is een kill-switch in de context van Not Running?

Kill-switch — een serveropdracht voor noodbeëindiging van de app. Wordt gebruikt in bank- en bedrijfsapps voor het op afstand blokkeren van toegang. Als de app een kill-opdracht heeft ontvangen, blokkeert deze bij de volgende koude start de UI en vraagt om herauthenticatie. In iOS wordt een kill-switch geïmplementeerd via remote notifications met een blokkeervlag.

Samenvatting

  • Not Running — begin- en eindtoestand van de levenscyclus, de app is niet in het geheugen geladen en voert geen code uit
  • Koude start — volledige herlading van de app vanuit Not Running, vereist initialisatie van alle componenten vanaf nul
  • Warme start — terugkeer uit Suspended, roept didFinishLaunchingWithOptions of Application.onCreate niet aan
  • Gegevens opslaan — van cruciaal belang bij overgang naar Background, omdat Not Running op elk moment kan optreden
  • iOS — applicationWillTerminate is niet gegarandeerd, toestand wordt opgeslagen via UserDefaults of state restoration
  • Android — proces kan op elk moment worden beëindigd, SavedStateHandle in ViewModel slaat toestand automatisch op
  • Startoptimalisatie — luie initialisatie, minimaal werk in main thread, SplashScreen API voor snel eerste frame

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook