Activity Lifecycle: cos'è, onCreate onStart onResume in Android

Autore: IT Sectr Pubblicato: 2026-03-03 Tempo di lettura: 12 min

L'Activity Lifecycle è un insieme di metodi di callback che Android chiama quando un'Activity transiziona tra stati: creazione, visibilità, focus di input, perdita parziale di visibilità, occultamento completo e distruzione. Il sistema gestisce il ciclo di vita di ogni schermata dell'applicazione, dal momento della chiamata di onCreate() fino a onDestroy(). Comprendere questi stati è un requisito obbligatorio per il funzionamento stabile di un'applicazione Android, poiché una gestione errata delle transizioni tra metodi porta a perdite di memoria, perdita di dati utente e crash imprevisti. Leggi di più sull'architettura di Android nell'articolo generale su Android.

Punti chiave

  • Activity Lifecycle — una sequenza rigorosamente definita di metodi: onCreate, onStart, onResume, onPause, onStop, onDestroy
  • onCreate — l'unico metodo obbligatorio, chiamato una volta alla creazione di un'Activity; qui vengono eseguiti l'inizializzazione dell'interfaccia utente e dei dati
  • onResume — l'Activity è in primo piano e interagisce con l'utente; questo è lo stato di lavoro dello schermo
  • onPause / onStop — quando si passa in secondo piano, l'Activity prima si mette in pausa, poi si ferma; i dati critici vengono salvati in onPause
  • onSaveInstanceState — meccanismo per salvare lo stato dell'interfaccia utente durante la rotazione dello schermo e la ricreazione dell'Activity da parte del sistema
  • Ciclo di vita di Fragment — simile ad Activity, ma integrato con i metodi onAttach, onCreateView, onViewCreated, onDestroyView
  • LifecycleObserver — componente Jetpack per il monitoraggio reattivo dello stato senza sovrascrivere metodi in Activity

Cos'è l'Activity Lifecycle

L'Activity Lifecycle (ciclo di vita di Activity) è una macchina a stati che ogni schermata di un'applicazione Android attraversa dal momento della creazione fino alla distruzione completa. Il sistema Android gestisce questo processo in base alle azioni dell'utente: apertura dell'applicazione, minimizzazione, rotazione dello schermo, risposta a una chiamata in arrivo, commutazione tra applicazioni e chiusura.

Comprendere il ciclo di vita è essenziale per ogni sviluppatore Android, poiché il sistema può distruggere un'Activity in qualsiasi momento in caso di memoria insufficiente — e l'applicazione deve ripristinare correttamente il suo stato. Secondo Google Android Vitals (2025), le applicazioni che non gestiscono il salvataggio dello stato in onSaveInstanceState() mostrano 42% di crash in più durante la ricreazione dell'Activity.

Il ciclo di vita include sei metodi callback principali: onCreate(), onStart(), onResume(), onPause(), onStop(), onDestroy(). Inoltre esiste il metodo onRestart(), chiamato prima di onStart() quando un'Activity ritorna dallo stato fermo. Ogni metodo ha uno scopo e un tempo di esecuzione rigorosamente definiti — il sistema li chiama sequenzialmente e lo sviluppatore può sovrascrivere qualsiasi di essi per implementare la propria logica.

Il ciclo può essere diviso in tre fasi chiave: durata completa (onCreate → onDestroy), durata visibile (onStart → onStop) e durata in primo piano (onResume → onPause). Comprendere questi tre livelli aiuta a distribuire correttamente il codice di inizializzazione e rilascio delle risorse.

Metodi del ciclo di vita di Activity

Ogni metodo del ciclo di vita esegue un compito rigorosamente definito. Il sistema li chiama in un ordine fisso e lo sviluppatore dovrebbe sovrascrivere solo i metodi necessari per la logica specifica. Non è raccomandato chiamare direttamente i metodi del ciclo di vita — questo è gestito da Android Runtime.

Schema generale delle chiamate

Una sequenza tipica all'avvio dell'applicazione: onCreate → onStart → onResume. Quando si preme il pulsante Indietro: onPause → onStop → onDestroy. Quando si minimizza: onPause → onStop, poi al ritorno: onRestart → onStart → onResume.

kotlin
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    override fun onStart() {
        super.onStart()
    }

    override fun onResume() {
        super.onResume()
    }

    override fun onPause() {
        super.onPause()
    }

    override fun onStop() {
        super.onStop()
    }

    override fun onDestroy() {
        super.onDestroy()
    }

    override fun onRestart() {
        super.onRestart()
    }
}

Ogni metodo sovrascritto deve chiamare la sua versione super — senza questo, il sistema non può completare correttamente la transizione di stato. Questa regola è stabilita nella documentazione di Android Developers ed è verificata dalle regole lint di Android Studio.

Tre livelli del ciclo di vita

Primo livello — durata completa: l'intervallo tra onCreate e onDestroy. Qui vengono eseguiti l'inizializzazione una tantum e il rilascio finale delle risorse globali. Secondo livello — durata visibile: tra onStart e onStop. L'Activity è visibile sullo schermo ma può essere parzialmente coperta da un'altra finestra. Terzo livello — durata in primo piano: tra onResume e onPause. L'Activity è in cima alla pila delle attività e interagisce con l'utente.

onCreate — creazione dell'Activity

onCreate() — il primo e unico metodo obbligatorio del ciclo di vita di Activity. Viene chiamato dal sistema una volta alla creazione di un'istanza di Activity. Questo metodo accetta un parametro savedInstanceState: Bundle?, che contiene lo stato precedentemente salvato se l'Activity viene ricreata dopo la distruzione — ad esempio, durante la rotazione dello schermo.

All'interno di onCreate vengono eseguiti i seguenti compiti: inizializzazione dell'interfaccia utente tramite setContentView() con una risorsa layout, collegamento degli elementi View tramite findViewById(), configurazione degli adapter per RecyclerView e ViewPager, ripristino dello stato da savedInstanceState, inizializzazione di ViewModel e LiveData, configurazione dei listener di clic e gesti. Il metodo dovrebbe completarsi il più rapidamente possibile — le operazioni lunghe qui bloccano il rendering del primo fotogramma, aumentando il tempo di avvio dell'applicazione.

kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_profile)

    val userNameText: TextView = findViewById(R.id.user_name)
    val loadButton: Button = findViewById(R.id.load_button)

    if (savedInstanceState != null) {
        userNameText.text = savedInstanceState.getString("user_name")
    }

    loadButton.setOnClickListener {
        loadUserProfile()
    }
}

Se l'Activity viene creata per la prima volta, savedInstanceState è null. Quando viene ricreata dopo una rotazione dello schermo, il Bundle contiene i dati salvati in onSaveInstanceState(). Il controllo di null è una pratica standard per ripristinare correttamente l'interfaccia utente senza perdere i dati inseriti dall'utente.

onStart — apparizione sullo schermo

onStart() viene chiamato immediatamente dopo onCreate() o dopo onRestart(), quando l'Activity diventa visibile all'utente. In questo stato, l'Activity non è ancora in primo piano e non può interagire con l'utente, ma la sua interfaccia utente è già visibile sullo schermo. Ad esempio, all'avvio dell'applicazione, il sistema renderizza il primo fotogramma dell'interfaccia tra le chiamate onStart e onResume.

Nel metodo onStart vengono tipicamente eseguite le seguenti azioni: avvio delle animazioni che dovrebbero funzionare mentre l'Activity è visibile; collegamento dei ricevitori di broadcast (BroadcastReceiver); connessione ai servizi di geolocalizzazione e ai sensori; aggiornamento dei dati da ViewModel o Room. Qui viene anche effettuato il collegamento ai servizi Bound tramite bindService() se l'applicazione utilizza un'architettura client-server all'interno del processo.

kotlin
override fun onStart() {
    super.onStart()
    val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
    locationManager.requestLocationUpdates(
        LocationManager.GPS_PROVIDER,
        5000L,
        10f,
        locationListener
    )
}

override fun onStop() {
    super.onStop()
    val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
    locationManager.removeUpdates(locationListener)
}

Regola importante: le risorse connesse in onStart devono essere rilasciate in onStop. Questo garantisce che quando l'Activity non è visibile sullo schermo, non consumi batteria e risorse di sistema. Google Play Store verifica le applicazioni per perdite di LocationListener e altri servizi di sistema durante la moderazione degli aggiornamenti.

onResume — ottenimento del focus

onResume() — lo stato in cui l'Activity è in primo piano e pronta a interagire con l'utente. Questo è lo stato di lavoro dello schermo: il sistema trasferisce il focus di input all'Activity e tutti gli eventi tattili, di input da tastiera e gesti vengono indirizzati a questo schermo. Il metodo onResume viene chiamato ogni volta che l'Activity ritorna in primo piano — dopo che un'altra Activity termina, dopo la chiusura di una finestra di dialogo o dopo lo sblocco del dispositivo.

In onResume vengono eseguiti: ripresa delle animazioni che sono state messe in pausa in onPause; apertura della fotocamera e di altre risorse esclusive; registrazione dei listener di sensori (accelerometro, giroscopio); avvio di timer e cronometro per l'interfaccia utente; aggiornamento del contenuto dello schermo con dati correnti. La coppia onResume/onPause viene utilizzata per le risorse che dovrebbero essere attive solo quando c'è focus — ad esempio, riconoscimento vocale continuo o acquisizione video.

kotlin
override fun onResume() {
    super.onResume()
    cameraHolder.openCamera()
    animator.resume()
    sensorManager.registerListener(
        stepCounter,
        sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER),
        SensorManager.SENSOR_DELAY_NORMAL
    )
}

override fun onPause() {
    super.onPause()
    cameraHolder.closeCamera()
    animator.pause()
    sensorManager.unregisterListener(stepCounter)
}

La differenza tra onStart e onResume è significativa: un'Activity può essere visibile (onStart) ma non attiva (onResume) — ad esempio, quando una finestra di dialogo pop-up o una schermata di blocco trasparente viene visualizzata sopra di essa. È in onResume, non in onStart, che le risorse esclusive che richiedono accesso esclusivo dovrebbero essere aperte.

onPause — perdita del focus

onPause() viene chiamato quando l'Activity perde il focus di input ma rimane parzialmente visibile. Scenari tipici: apertura di una finestra di dialogo, pressione del pulsante App recenti, una chiamata in arrivo, pressione del pulsante Home (in questo caso onPause sarà seguito da onStop). Il metodo onPause è l'ultimo posto affidabile per salvare i dati che l'utente non dovrebbe perdere.

In onPause vengono eseguiti: salvataggio di bozze di email e moduli di input in Room o SharedPreferences; arresto di animazioni e riproduzione video; chiusura della fotocamera e rilascio di risorse esclusive; cancellazione di operazioni costose non critiche in secondo piano. Il metodo onPause dovrebbe completarsi in meno di 100 millisecondi — il sistema blocca la transizione all'Activity successiva fino a quando onPause non restituisce il controllo e il superamento del limite porta ad ANR (Application Not Responding).

kotlin
override fun onPause() {
    super.onPause()
    val editor = SharedPreferences.Manager ...
    editor.putString("draft_text", draftEditText.text.toString())
    editor.apply()
    videoView.pause()
    cameraHolder.release()
}

Importante: onPause viene eseguito nel thread dell'interfaccia utente, quindi qualsiasi operazione bloccante come la scrittura nel database tramite Room con una query sincrona dovrebbe essere sostituita con operazioni asincrone (coroutine) o eseguita in un thread in secondo piano. Usa apply() invece di commit() per SharedPreferences — apply scrive i dati in modo asincrono e non blocca il thread dell'interfaccia utente.

onStop — occultamento dallo schermo

onStop() viene chiamato quando l'Activity cessa di essere visibile all'utente. Ciò si verifica nei seguenti casi: l'Activity è completamente coperta da un'altra Activity; l'utente ha premuto il pulsante Home o è passato a un'altra applicazione; l'Activity sta terminando (successivamente verrà chiamato onDestroy). Nello stato onStop, l'Activity rimane in memoria e conserva tutti i suoi campi — non è distrutta, ma nemmeno attiva.

In onStop vengono eseguiti: deregistrazione dei BroadcastReceiver registrati in onStart; disconnessione dai servizi Bound; rilascio di LocationListener, SensorListener e altri listener di sistema; arresto di operazioni in secondo piano di lunga durata che non sono necessarie quando l'applicazione è nascosta; scrittura dello stato corrente dell'interfaccia utente in un Bundle tramite onSaveInstanceState() se non è stato fatto in onPause.

kotlin
override fun onStop() {
    super.onStop()
    unregisterReceiver(connectivityReceiver)
    unbindService(serviceConnection)
    if (isChangingConfigurations()) {
        Log.d("Lifecycle", "L'Activity viene ricreata a causa della configurazione")
    }
}

Il sistema può distruggere un'Activity nello stato onStop senza chiamare onDestroy in caso di memoria insufficiente. Pertanto, tutti i dati critici devono essere salvati prima della transizione a onStop. Il flag isChangingConfigurations() permette di determinare se la chiamata a onStop è correlata alla rotazione dello schermo — in questo caso, l'Activity verrà ricreata, non terminata.

onDestroy — distruzione dell'Activity

onDestroy() — l'ultimo metodo del ciclo di vita chiamato prima della distruzione completa dell'Activity. Il sistema chiama onDestroy in due casi: l'Activity termina tramite finish() o l'utente preme il pulsante Indietro; l'Activity viene distrutta dal sistema a causa di un cambiamento di configurazione (ad esempio, rotazione dello schermo) e verrà creata di nuovo. Il metodo onDestroy permette di eseguire la pulizia finale delle risorse: scollegamento di thread e coroutine, chiusura di cursori e socket aperti permanentemente e rilascio di memoria nativa tramite NDK.

kotlin
override fun onDestroy() {
    super.onDestroy()
    backgroundJob.cancel()
    dbHelper.close()
    if (isFinishing) {
        Log.d("Lifecycle", "L'Activity sta terminando definitivamente")
    } else {
        Log.d("Lifecycle", "L'Activity verrà ricreata")
    }
}

Nota importante: onDestroy non è garantito se il processo dell'applicazione viene ucciso dal sistema (out-of-memory kill). Pertanto, non si può fare affidamento su onDestroy per salvare i dati — questo compito viene risolto in onPause o onStop. La proprietà isFinishing permette di distinguere la terminazione dell'Activity tramite finish() dalla ricreazione dovuta a cambiamenti di configurazione.

onRestart — ritorno dallo stato fermo

onRestart() viene chiamato prima di onStart() quando un'Activity ritorna dallo stato fermo (onStop) al primo piano. Ciò accade quando l'utente riapre l'applicazione dal menu App recenti o ritorna a un'Activity premendo Indietro in una schermata figlia. Il metodo onRestart permette di eseguire una logica diversa da onCreate — ad esempio, aggiornare i dati che potrebbero essere cambiati mentre l'Activity era nascosta.

kotlin
override fun onRestart() {
    super.onRestart()
    refreshDataFromNetwork()
    Log.d("Lifecycle", "L'Activity si sta riavviando dalla pila")
}

Scenario tipico: l'utente ha aperto l'applicazione, è passato a un'altra attività ed è tornato un'ora dopo. In onRestart, l'applicazione può verificare l'attualità dei dati e, se è passato molto tempo, suggerire di ricaricare il contenuto. Questo migliora l'esperienza utente e riduce la probabilità di visualizzare informazioni obsolete.

Rotazione dello schermo e salvataggio dello stato

La rotazione dello schermo è lo scenario più comune di ricreazione dell'Activity. Per impostazione predefinita, Android distrugge l'Activity corrente e ne crea una nuova a ogni cambiamento di orientamento. Se lo stato non viene salvato, l'utente perderà tutti i dati inseriti. Android fornisce due meccanismi per questo: onSaveInstanceState() per i dati serializzabili e ViewModel per i dati che sopravvivono ai cambiamenti di configurazione.

onSaveInstanceState e onRestoreInstanceState

onSaveInstanceState() viene chiamato prima della distruzione dell'Activity per salvare lo stato temporaneo. I dati salvati vengono passati a onCreate tramite il parametro savedInstanceState e al metodo onRestoreInstanceState(), chiamato dopo onStart. Il Bundle ha un limite di dimensione — circa 500 KB, quindi grandi volumi di dati (ad esempio, bitmap) vengono salvati tramite ViewModel.

xml
<!-- AndroidManifest.xml — fissaggio dell'orientamento -->
<activity android:name=".MainActivity"
    android:configChanges="orientation|screenSize" />

Il fissaggio dell'orientamento tramite android:configChanges impedisce la ricreazione dell'Activity, ma è considerato un antipattern se l'applicazione deve supportare entrambi gli orientamenti. La raccomandazione moderna di Google è di usare ViewModel in combinazione con onSaveInstanceState per i dati che l'utente inserisce nell'interfaccia utente.

Ciclo di vita di Fragment

Fragment ha un proprio ciclo di vita, simile ad Activity, ma con metodi aggiuntivi: onAttach, onCreate, onCreateView, onViewCreated, onStart, onResume, onPause, onStop, onDestroyView, onDestroy, onDetach. Un Fragment esiste sempre all'interno di un'Activity e il suo ciclo di vita è legato al ciclo di vita dell'Activity contenitore. Se l'Activity viene distrutta, il Fragment la segue.

La differenza principale: Fragment gestisce non solo lo stato del componente, ma anche la gerarchia delle View. Il metodo onCreateView restituisce la View radice del Fragment e onDestroyView distrugge questa gerarchia. Questo permette al Fragment di sopravvivere alla ricreazione dell'Activity durante la rotazione dello schermo: il Fragment viene conservato e la sua View viene ricreata in onCreateView.

kotlin
class ProfileFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return inflater.inflate(R.layout.fragment_profile, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val avatarImage: ImageView = view.findViewById(R.id.avatar_image)
        loadAvatar(avatarImage)
    }
}

Comprendere la differenza tra onCreate e onCreateView è criticamente importante: onCreate viene chiamato una volta per vita del Fragment (anche quando la View viene ricreata), mentre onCreateView viene chiamato ogni volta che il Fragment crea o ricrea la sua gerarchia di View. L'inizializzazione dei dati viene eseguita in onCreate, mentre il collegamento dell'interfaccia utente viene eseguito in onViewCreated.

LifecycleObserver e Jetpack

LifecycleObserver — un componente della libreria Android Jetpack che permette di reagire ai cambiamenti del ciclo di vita senza sovrascrivere metodi in Activity o Fragment. Invece di duplicare il codice in ogni metodo del ciclo di vita, lo sviluppatore crea una classe separata con annotazioni @OnLifecycleEvent e la passa a lifecycle.addObserver().

Jetpack fornisce anche l'interfaccia LifecycleOwner, che è implementata da AppCompatActivity e Fragment. Qualsiasi oggetto che implementa LifecycleOwner può gestire abbonamenti LiveData, coroutine tramite lifecycleScope e WorkManager in relazione al ciclo di vita. Questa è una pietra angolare dell'architettura moderna di Android basata su MVVM e Jetpack.

kotlin
class MyLocationObserver(private val context: Context) : DefaultLifecycleObserver {
    override fun onStart(owner: LifecycleOwner) {
        startLocationUpdates()
    }

    override fun onStop(owner: LifecycleOwner) {
        stopLocationUpdates()
    }
}

// In Activity:
lifecycle.addObserver(MyLocationObserver(this))

L'uso di DefaultLifecycleObserver semplifica i test, riduce la duplicazione del codice e rende la logica del ciclo di vita riutilizzabile tra diverse schermate. Questa è una sostituzione moderna della sovrascrittura manuale di onStart/onStop in ogni Activity. Nelle applicazioni Android sviluppate da IT Sectr, applichiamo LifecycleObserver per geolocalizzazione, scansione Bluetooth e analisi — questo riduce il volume di codice boilerplate del 30–40%.

Domande frequenti

Cosa succede se non si chiama super nei metodi del ciclo di vita?

Se non si chiama super.onCreate() o qualsiasi altro metodo super del ciclo di vita, il sistema lancerà un'eccezione SuperNotCalledException e l'applicazione si bloccherà. Questo è un requisito rigoroso di Android Runtime — ogni metodo deve delegare l'esecuzione alla classe base, altrimenti la macchina a stati interna non può transizionare allo stato successivo.

Perché l'Activity viene ricreata quando si ruota lo schermo?

L'Activity viene ricreata quando si ruota lo schermo perché il cambiamento di orientamento è un cambiamento di configurazione del dispositivo. Per impostazione predefinita, Android distrugge l'Activity e ne crea una nuova per caricare risorse alternative (layout-land, values-land). Per disabilitare la ricreazione, è possibile aggiungere l'attributo android:configChanges nel manifesto, ma Google raccomanda di usare ViewModel per preservare i dati.

In quale metodo i dati dovrebbero essere salvati prima di chiudere l'applicazione?

I dati critici vengono salvati in onPause(), poiché questo è l'ultimo metodo garantito di essere chiamato prima che l'applicazione possa essere uccisa dal sistema. Dopo onStop e onDestroy, il sistema può terminare il processo senza chiamare metodi aggiuntivi. Per bozze e dati intermedi, usa SharedPreferences con apply() o Room con coroutine.

Qual è la differenza tra onPause e onStop?

onPause viene chiamato quando l'Activity perde il focus ma rimane parzialmente visibile (ad esempio, una finestra di dialogo viene aperta). onStop viene chiamato quando l'Activity è completamente nascosta dallo schermo da un'altra Activity o premendo il pulsante Home. La principale differenza pratica: onPause è l'ultimo punto per salvare i dati, onStop è il luogo per rilasciare listener e servizi di sistema che non sono necessari in secondo piano.

Cos'è ViewModel e come si relaziona con il ciclo di vita?

ViewModel è un componente Android Jetpack che memorizza i dati dell'interfaccia utente e sopravvive automaticamente ai cambiamenti di configurazione (rotazione dello schermo). ViewModel non viene distrutto quando l'Activity viene ricreata: vive fino a quando il LifecycleOwner (Activity o Fragment) non viene terminato completamente. Questo risolve il problema di preservare i dati durante la rotazione dello schermo senza usare Bundle e onSaveInstanceState. ViewModel è un elemento obbligatorio dell'architettura MVVM raccomandata da Google.

Riepilogo

  • Activity Lifecycle — una sequenza di metodi onCreate, onStart, onResume, onPause, onStop, onDestroy, ciascuno responsabile di una fase specifica del funzionamento dello schermo
  • onCreate — inizializzazione dell'interfaccia utente e ottenimento di savedInstanceState durante la ricreazione; l'unico metodo obbligatorio
  • onStart / onStop — coppia per gestire la visibilità: registrazione e rilascio di listener e servizi di sistema
  • onResume / onPause — coppia per gestire il focus: le risorse esclusive (fotocamera, sensori) vengono aperte in onResume e chiuse in onPause
  • Rotazione dello schermo — ricrea l'Activity per impostazione predefinita; la conservazione dello stato tramite onSaveInstanceState + ViewModel è una pratica standard
  • Ciclo di vita di Fragment — integrato con i metodi onAttach, onCreateView, onViewCreated, onDestroyView, onDetach; la View viene creata e distrutta separatamente dal Fragment stesso
  • LifecycleObserver — componente Jetpack per il monitoraggio reattivo del ciclo di vita senza duplicare codice in Activity
  • ViewModel — sopravvive ai cambiamenti di configurazione e risolve il problema della perdita di dati durante la rotazione dello schermo senza salvataggio manuale in Bundle
  • Regola super — ogni metodo sovrascritto del ciclo di vita deve chiamare la sua versione super, altrimenti il sistema lancerà SuperNotCalledException

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche