Android Kotlin Fundamentals 04.1: cicli di vita e logging

Questo codelab fa parte del corso Android Kotlin Fundamentals. Otterrai il massimo valore da questo corso se lavori in sequenza nei codelab. Tutti i codelab del corso sono elencati nella pagina di destinazione di Android Kotlin Fundamentals.

Introduzione

In questo codelab, scoprirai una parte fondamentale di Android: l'attività e il ciclo di vita dei frammenti. Il ciclo di vita delle attività è l'insieme di stati in cui può trovarsi un'attività durante il suo ciclo di vita. Il ciclo di vita si estende dal momento in cui l'attività viene creata inizialmente a quando viene eliminata e il sistema recupera le risorse di tale attività. Quando un utente naviga tra le attività nella tua app (e all'interno e all'esterno della tua app), ciascuna di queste attività cambia tra i vari stati del ciclo di vita dell'attività.

Il ciclo di vita dei frammenti è molto simile a quello delle attività. Questo codelab è incentrato principalmente sulle attività, con un rapido sguardo ai frammenti verso la fine.

In qualità di sviluppatore Android, devi conoscere il ciclo di vita dell'attività. Se le tue attività non rispondono correttamente ai cambiamenti dello stato del ciclo di vita, l'app potrebbe generare strani bug, confondere i comportamenti degli utenti o utilizzare troppe risorse del sistema Android. Comprendere il ciclo di vita di Android e rispondere correttamente ai cambiamenti dello stato del ciclo di vita è fondamentale per essere un buon cittadino Android.

Cosa dovresti sapere

  • Che cos'è un'attività e come crearne una nell'app.
  • Cosa fa il metodo onCreate() dell'attività e il tipo di operazioni eseguite in tale metodo.
  • Come creare layout XML per la tua attività e come aggiornare un layout in fase di esecuzione.

Cosa imparerai a fare:

  • Come stampare informazioni di logging nel logcat (a volte chiamato console Android o monitor Android).
  • Nozioni di base sui cicli di vita Activity e Fragment e i callback che vengono richiamati quando l'attività passa da uno stato all'altro.
  • Come sostituire i metodi di callback del ciclo di vita per eseguire operazioni in momenti diversi nel ciclo di vita dell'attività.
  • Come utilizzare la libreria Timber per accedere all'app.

Cosa dovrai fare

  • Modifica un'app iniziale denominata DessertClicker per aggiungere informazioni di logging visualizzate in Logcat.
  • Esegui l'override dei metodi di callback del ciclo di vita e registra le modifiche allo stato dell'attività.
  • Esegui l'app e prendi nota delle informazioni di logging visualizzate quando l'attività viene avviata, interrotta e ripresa.
  • Modifica l'app per utilizzare la libreria Timber.
  • Aggiungi il logging all'app AndroidTrivia e monitora le modifiche agli stati dei frammenti.

In questo codelab, lavori con un'app iniziale chiamata DessertClicker. In questa app, ogni volta che l'utente tocca un dessert sullo schermo, l'app "acquista" il dessert per l'utente. L'app aggiorna i valori nel layout per il numero di dessert acquistati e per l'importo totale speso dall'utente.

Questa app contiene diversi bug relativi al ciclo di vita di Android: ad esempio, in determinate circostanze l'app reimposta i valori del dessert su 0 e l'app continua a utilizzare le risorse di sistema anche quando l'app è in background. Conoscere il ciclo di vita di Android ti aiuterà a capire perché si verificano questi problemi e come risolverli.

Ogni attività e ogni frammento ha un cosiddetto ciclo di vita. Si tratta di un'allusione ai cicli di vita degli animali, come il ciclo di vita di questa farfalla, i diversi stati della farfalla mostrano la sua crescita dalla nascita all'età adulta fino alla morte.

Allo stesso modo, il ciclo di vita delle attività è costituito dai diversi stati in cui può verificarsi un'attività, dalla prima inizializzazione dell'attività fino alla sua eliminazione e alla sua memoria da parte del sistema. Quando l'utente avvia l'app, naviga tra le attività, naviga all'interno e all'esterno dell'app e lascia l'app, lo stato dell'attività cambia. Il diagramma seguente mostra tutti gli stati del ciclo di vita delle attività. Come indicano i loro nomi, questi stati rappresentano lo stato dell'attività.

Spesso potresti voler modificare un comportamento oppure eseguire codice quando lo stato del ciclo di vita dell'attività cambia. Pertanto, la classe Activity stessa e le eventuali sottoclassi di Activity, come AppCompatActivity, implementano un insieme di metodi di callback del ciclo di vita. Android richiama questi callback quando l'attività passa da uno stato all'altro. Puoi sostituire questi metodi nelle tue attività per eseguire attività in risposta a tali cambiamenti dello stato del ciclo di vita. Il seguente diagramma mostra gli stati del ciclo di vita insieme ai callback richiamabili disponibili.

Un frammento ha anche un ciclo di vita. Il ciclo di vita di un frammento è simile al ciclo di vita di un'attività, quindi gran parte di ciò che apprendi viene applicato a entrambi. In questo codelab, ti concentri sul ciclo di vita dell'attività perché è una parte fondamentale di Android e il più facile da osservare in un'app semplice. Ecco il diagramma corrispondente per il ciclo di vita dei frammenti:

È importante sapere quando vengono richiamati e cosa fare in ogni metodo di richiamata. Entrambi i diagrammi sono però complessi e possono confondere. In questo codelab, invece di limitarti a leggere cosa significa ogni stato e richiamata, stai svolgendo un'attività di investigazione e imparerai a capire cosa sta succedendo.

Passaggio 1: esamina il metodo onCreate() e aggiungi il logging

Per capire il motivo del ciclo di vita di Android, è utile sapere quando vengono chiamati i vari metodi del ciclo di vita. Questo ti aiuterà a individuare i problemi in DessertClicker.

Un modo semplice per farlo è utilizzare l'API Android Logging. Durante la registrazione, Logging ti consente di scrivere brevi messaggi su una console e puoi utilizzarlo per mostrare quando vengono attivati callback diversi.

  1. Scarica l'app iniziale di DessertClicker e aprila in Android Studio.
  2. Compila ed esegui l'app e tocca diverse volte l'immagine del dessert. Nota come il valore dei Dessert venduti e il totale degli importi cambiano.
  3. Apri MainActivity.kt ed esamina il metodo onCreate() per questa attività
override fun onCreate(savedInstanceState: Bundle?) {
...
}

Nel diagramma del ciclo di vita dell'attività potresti aver riconosciuto il metodo onCreate(), perché hai già utilizzato questo callback. È l'unico metodo che deve essere implementato da ogni attività. Il metodo onCreate() è lo strumento in cui devi eseguire le iniziali una tantum per la tua attività. Ad esempio, in onCreate() puoi gonfiare il layout, definire i listener di clic o impostare l'associazione di dati.

Il metodo del ciclo di vita onCreate() viene richiamato una volta, subito dopo l'inizializzazione dell'attività (quando viene creato il nuovo oggetto Activity in memoria). Una volta eseguita onCreate(), l'attività viene considerata creata.

  1. Nel metodo onCreate(), subito dopo la chiamata a super.onCreate(), aggiungi la seguente riga. Se necessario, importa la classe Log. Premi Alt+Enter o Option+Enter su un Mac e seleziona Importa.
Log.i("MainActivity", "onCreate Called")

La classe Log scrive i messaggi nel logcat. Questo comando prevede tre parti:

  • La gravità del messaggio di log, ovvero l'importanza del messaggio. In questo caso, il metodo Log.i() scrive un messaggio informativo. Altri metodi nella classe Log includono Log.e() per gli errori o Log.w() per gli avvisi.
  • Il tag del log, in questo caso "MainActivity". Il tag è una stringa che consente di trovare più facilmente i messaggi di log in Logcat. In genere il tag corrisponde al nome della classe.
  • Il messaggio di log effettivo, una breve stringa, che in questo caso è "onCreate called".
  1. Compila ed esegui l'app DessertClicker. Non vedi alcuna differenza di comportamento nell'app quando tocchi il dessert. In Android Studio, fai clic sulla scheda Logcat nella parte inferiore dello schermo.



    Logcat è la console per registrare i messaggi. I messaggi relativi ad Android relativi alla tua app vengono visualizzati qui, inclusi i messaggi che invii esplicitamente al log con il metodo Log.i() o con altri metodi di classe Log.
  2. Nel riquadro Logcat, digita I/MainActivity nel campo di ricerca.


    Il logcat può contenere molti messaggi, la maggior parte dei quali non è utile per te. Puoi filtrare le voci Logcat in molti modi, ma la ricerca è la più semplice. Poiché hai utilizzato MainActivity come tag di log nel codice, puoi utilizzarlo per filtrare il log. Se aggiungi I/ all'inizio, significa che si tratta di un messaggio informativo creato da Log.i().

    Il messaggio di log include la data e l'ora, il nome del pacchetto (com.example.android.dessertclicker), il tag del log (con I/ all'inizio) e il messaggio effettivo. Poiché questo messaggio appare nel log, sai che onCreate() è stato eseguito.

Passaggio 2: implementa il metodo onStart()

Il metodo del ciclo di vita onStart() viene chiamato subito dopo onCreate(). Dopo l'esecuzione di onStart(), l'attività sarà visibile sullo schermo. A differenza di onCreate(), che viene chiamato una sola volta per inizializzare la tua attività, onStart() può essere chiamato molte volte nel ciclo di vita dell'attività.

Tieni presente che onStart() è accoppiato a un metodo di ciclo di vita di onStop() corrispondente. Se l'utente avvia l'app e poi torna alla schermata Home del dispositivo, l'attività viene interrotta e non è più visibile sullo schermo.

  1. In Android Studio, con l'app MainActivity.kt aperta, seleziona Codice > Sostituisci metodi o premi Control+o. Viene visualizzata una finestra di dialogo con un elenco enorme di tutti i metodi che puoi sostituire in questo corso.
  2. Inizia a inserire onStart per cercare il metodo giusto. Per scorrere fino all'elemento corrispondente successivo, utilizza la Freccia giù. Scegli onStart() dall'elenco e fai clic su OK per inserire il codice di sostituzione della caldaia. Il codice ha il seguente aspetto:
override fun onStart() {
   super.onStart()
}
  1. All'interno del metodo onStart(), aggiungi un messaggio di log:
override fun onStart() {
   super.onStart()

   Log.i("MainActivity", "onStart Called")
}
  1. Compila ed esegui l'app DessertClicker e apri il riquadro Logcat. Digita I/MainActivity nel campo di ricerca per filtrare il log. Tieni presente che entrambi i metodi onCreate() e onStart() sono stati chiamati uno dopo l'altro e che la tua attività è visibile sullo schermo.
  2. Premi il pulsante Home sul dispositivo, quindi usa la schermata recente per tornare all'attività. Nota che l'attività riprende da dove si era interrotta, con gli stessi valori, e che onStart() viene registrato una seconda volta in Logcat. Tieni presente inoltre che il metodo onCreate() di solito non viene richiamato.

In questa attività modificherai l'app in modo che utilizzi una libreria di logging molto diffusa chiamata Timber. Timber offre diversi vantaggi rispetto alla classe integrata Log di Android. In particolare, la libreria di Timber:

  • Genera il tag di log per te in base al nome della classe.
  • Ti aiuta a evitare di mostrare i log in una versione di release della tua app Android.
  • Consente l'integrazione con librerie di report sugli arresti anomali.

Vedrai subito il primo vantaggio; gli altri che apprezzerai man mano che crei e spedisci app più grandi.

Passaggio 1: aggiungi legno a Gradle

  1. Visita questo link al progetto Timber su GitHub e copia la riga di codice nell'intestazione Download che inizia con la parola implementation. La riga di codice sarà simile a questa, anche se il numero di versione potrebbe essere diverso.
implementation 'com.jakewharton.timber:timber:4.7.1'
  1. In Android Studio, nella vista Progetto: Android, espandi Script di Gradle e apri il file build.gradle (Modulo: app).
  2. All'interno della sezione delle dipendenze, incolla la riga di codice che hai copiato.
dependencies {
   ...
   implementation 'com.jakewharton.timber:timber:4.7.1'
}
  1. Fai clic sul link Sincronizza ora in alto a destra di Android Studio per ricostruire Gradle. La build deve essere eseguita senza errori.

Passaggio 2: crea una classe Application e inizializza il legno

In questo passaggio, creerai un corso Application. Application è una classe base che contiene lo stato dell'applicazione globale per l'intera app. È anche l'oggetto principale che il sistema operativo utilizza per interagire con l'app. Esiste una classe Application predefinita che Android utilizza se non ne specifichi uno, quindi c'è sempre un oggetto Application creato per la tua app, senza che tu debba fare nulla di speciale.

Timber utilizza la classe Application perché l'intera app utilizzerà questa libreria di logging e la libreria deve essere inizializzata una volta prima di tutto il resto. In casi come questo, puoi sottoclasse la classe Application e sostituire le impostazioni predefinite con la tua implementazione personalizzata.

Dopo aver creato il corso Application, devi specificare la classe nel file manifest Android.

  1. Nel pacchetto dessertclicker, crea una nuova classe Kotlin denominata ClickerApplication. A tal fine, espandi app > java e fai clic con il pulsante destro del mouse su com.example.android.dessertclicker. Seleziona New > Kotlin File/Class.
  2. Assegna alla classe il nome ClickerApplication e imposta Kind su Class. Fai clic su OK.

Android Studio crea un nuovo corso ClickerApplication e lo apre nell'editor di codice. Il codice ha il seguente aspetto:

package com.example.android.dessertclicker

class ClickerApplication {
}
  1. Modifica la definizione della classe in una sottoclasse di Application e importa la classe Application, se necessario.
class ClickerApplication : Application() {
  1. Per eseguire l'override del metodo onCreate(), seleziona Codice > Metodi di override o premi Control+o.
class ClickerApplication : Application() {
   override fun onCreate() {
       super.onCreate()
   }
}
  1. All'interno di quel metodo onCreate(), inizializza la libreria di Timber:
override fun onCreate() {
    super.onCreate()

    Timber.plant(Timber.DebugTree())
}

Questa riga di codice inizializza la libreria Timber per la tua app e ti consente di utilizzarla nelle tue attività.

  1. Apri AndroidManifest.xml.
  2. Nella parte superiore dell'elemento <application>, aggiungi un nuovo attributo per la classe ClickerApplication, in modo che Android sappia come utilizzare la classe Application anziché quella predefinita.
<application
   android:name=".ClickerApplication"
...

Passaggio 3: aggiungi istruzioni sui log di legno

In questo passaggio devi modificare le chiamate Log.i() per utilizzare Timber, quindi implementerai il logging per tutti gli altri metodi del ciclo di vita.

  1. Apri MainActivity e scorri fino a onCreate(). Sostituisci Log.i() con Timber.i() e rimuovi il tag di log.
Timber.i("onCreate called")

Come la classe Log, Timber utilizza anche il metodo i() per i messaggi informativi. Ricorda che con Timber non è necessario aggiungere un tag di log: Timber utilizza automaticamente il nome della classe come tag di log.

  1. Allo stesso modo, cambia la chiamata Log in onStart():
override fun onStart() {
   super.onStart()

   Timber.i("onStart Called")
}
  1. Compila ed esegui l'app DessertClicker e apri Logcat. Tieni presente che vengono visualizzati gli stessi messaggi di log di onCreate() e onStart(), ma ora è in corso la generazione dei messaggi Timber, non della classe Log.
  2. Sostituisci gli altri metodi del ciclo di vita in MainActivity e aggiungi istruzioni di log Timber per ognuno. Ecco il codice:
override fun onResume() {
   super.onResume()
   Timber.i("onResume Called")
}

override fun onPause() {
   super.onPause()
   Timber.i("onPause Called")
}

override fun onStop() {
   super.onStop()
   Timber.i("onStop Called")
}

override fun onDestroy() {
   super.onDestroy()
   Timber.i("onDestroy Called")
}

override fun onRestart() {
   super.onRestart()
   Timber.i("onRestart Called")
}
  1. Compila ed esegui di nuovo DessertClicker ed esamina Logcat. Questa volta notare che oltre a onCreate() e onStart(), c'è un messaggio di log per il callback del ciclo di vita onResume().

Quando un'attività inizia da zero, vedrai tutti e tre questi callback di ciclo di vita chiamati in ordine:

  • onCreate() per creare l'app.
  • onStart() per avviarla e renderla visibile sullo schermo.
  • onResume() per concentrare l'attività e renderla pronta per l'interazione da parte dell'utente.

Nonostante il nome, il metodo onResume() viene chiamato all'avvio, anche se non è possibile riprendere.

Ora che l'app DessertClicker è configurata per il logging, puoi iniziare a utilizzare l'app in vari modi e scoprire come vengono attivati i callback del ciclo di vita in risposta a tali utilizzi.

Caso d'uso 1: apertura e chiusura dell'attività

Inizierai dal caso d'uso più semplice, che consiste nell'avviare l'app per la prima volta, per poi chiudere completamente l'app.

  1. Compila ed esegui l'app DessertClicker, se non è già in esecuzione. Come hai visto, i callback onCreate(), onStart() e onResume() vengono chiamati quando l'attività inizia per la prima volta.
  2. Tocca un po' di cupcake.
  3. Tocca il pulsante Indietro sul dispositivo. Come puoi notare in Logcat, onPause(), onStop() e onDestroy() vengono chiamati in questo ordine.

    In questo caso, l'utilizzo del pulsante Indietro fa sì che l'attività (e l'app) venga completamente chiusa. L'esecuzione del metodo onDestroy() indica che l'attività è stata arrestata completamente e può essere raccolta nel cestino. La raccolta di rifiuti si riferisce alla pulizia automatica degli oggetti che non utilizzerai più. Quando onDestroy() viene chiamato, il sistema operativo sa che quelle risorse sono eliminabili e inizia a ripulire la memoria.

    La tua attività potrebbe inoltre essere interrotta del tutto se il codice chiama manualmente il metodo finish() dell'attività o se l'utente abbandona forzatamente l'app (ad esempio, l'utente può forzare l'uscita dall'app nella schermata recente facendo clic sulla X nell'angolo della finestra). Il sistema Android potrebbe anche interrompere la tua attività autonomamente se l'app non è stata visualizzata sullo schermo per molto tempo. In questo modo Android conserva la batteria e permette alle altre app di utilizzare le altre app.
  4. Usa la schermata recente per tornare all'app. Ecco Logcat:


    L'attività è stata eliminata nel passaggio precedente, quindi quando torni all'app, Android avvia una nuova attività e chiama i metodi onCreate(), onStart() e onResume(). Nota che nessuna delle statistiche di DessertClicker relative all'attività precedente è stata conservata.

    Il punto chiave qui è che onCreate() e onDestroy() vengono chiamati una sola volta per tutta la durata di una singola istanza dell'attività: onCreate() per inizializzare l'app per la prima volta e onDestroy() per pulire le risorse utilizzate dalla tua app.

    Il metodo onCreate() è un passaggio importante, ed è qui che esegui tutte le tue prime operazioni di inizializzazione, dove configuri il layout per la prima volta gonfiando e dove inizializza le variabili.

Caso d'uso 2: allontanarsi e tornare all'attività

Ora che hai avviato l'app e l'hai chiusa completamente, hai notato la maggior parte degli stati del ciclo di vita relativi alla prima attività. Hai visto anche tutti gli stati del ciclo di vita che si verificano quando l'attività si arresta completamente e viene eliminata. Man mano che gli utenti interagiscono con i propri dispositivi Android, passano da un'app all'altra, tornano a casa, avviano nuove app e gestiscono le interruzioni da parte di altre attività, ad esempio le telefonate.

La tua attività non si chiude completamente ogni volta che l'utente esce da tale attività:

  • Quando la tua attività non è più visibile sullo schermo, questa operazione viene chiamata inserimento in background. Il contrario si verifica quando l'attività è in primo piano o sullo schermo.
  • Quando l'utente torna all'app, la stessa attività viene riavviata e diventa di nuovo visibile. Questa parte del ciclo di vita è chiamata ciclo di vita visibile dell'app.

Quando la tua app è in background, non deve essere in esecuzione per preservare le risorse di sistema e la durata della batteria. Puoi utilizzare il ciclo di vita di Activity e i relativi callback per sapere quando l'app verrà spostata in background, in modo da poter mettere in pausa qualsiasi operazione in corso. Quindi riavvii le operazioni quando l'app passa in primo piano.

Ad esempio, supponiamo che un'app esegua una simulazione di fisica. Per decidere dove posizionare tutti gli oggetti nella simulazione e per visualizzarli, sono necessari molti calcoli, analizzati sulla CPU del dispositivo. Se una telefonata interrompe la simulazione, l'utente potrebbe confondersi o persino contrariarsi a tornare nell'app e vedere che la simulazione è terminata.

Il motivo è anche un motivo del rendimento. Supponiamo che l'utente abbia aperto 20 app che utilizzano simulazioni di fisica che richiedono molta CPU. Se queste app non sono visualizzate sullo schermo ma stanno ancora effettuando molti calcoli di rendering in background, questa operazione rallenterà le prestazioni dell'intero telefono.

In questo passaggio, puoi osservare il ciclo di vita dell'attività quando l'app passa in background e torna in primo piano.

  1. Con l'app DessertClicker in esecuzione, fai clic sul cupcake alcune volte.
  2. Premi il pulsante Home sul tuo dispositivo e osserva il logcat in Android Studio. Tornando alla schermata Home, l'app viene spostata in background anziché chiuderla del tutto. Nota che sono stati chiamati i metodi onPause() e onStop(), ma non il metodo onDestroy().


    Quando viene chiamato onPause(), l'app non è più attiva. Dopo onStop(), l'app non sarà più visibile sullo schermo. Anche se l'attività è stata interrotta, l'oggetto Activity è ancora in memoria, in background. L'attività non è stata eliminata. L'utente potrebbe tornare all'app, quindi Android mantiene le risorse relative alle tue attività.
  3. Utilizza la schermata delle recenti per tornare all'app. Nota in Logcat che l'attività viene riavviata con onRestart() e onStart(), quindi riprende con onResume().


    Quando l'attività torna in primo piano, il metodo onCreate() non viene richiamato. L'oggetto attività non è stato eliminato, quindi non deve essere creato di nuovo. Al posto di onCreate(), viene chiamato il metodo onRestart(). Tieni presente che questa volta che l'attività torna in primo piano, viene conservato il numero di Dessert venduti.
  4. Avvia almeno un'app diversa da DessertClicker in modo che sul dispositivo siano disponibili alcune app recenti.
  5. Mostra la schermata delle voci recenti e apri un'altra attività recente. Quindi torna alle app recenti e riporta DessertClicker in primo piano.

    Tieni presente che in Logcat vengono visualizzati gli stessi callback che hai selezionato quando hai premuto il pulsante Home. onPause() e onStop() vengono chiamati quando l'app passa in background, quindi onRestart(), onStart() e onResume() quando torna.

    Il punto importante in questo caso è che onStart() e onStop() vengono chiamati più volte mentre l'utente si sposta all'interno dell'attività. Dovresti eseguire l'override di questi metodi per interrompere l'app quando passa in background, o riavviarla quando torna in primo piano.

    Cosa succede con onRestart()? Il metodo onRestart() è molto simile a onCreate(). onCreate() o onRestart() vengono chiamati prima che l'attività diventi visibile. Il metodo onCreate() viene chiamato solo la prima volta, seguito da onRestart(). Il metodo onRestart() è uno strumento per inserire il codice che vuoi chiamare solo se l'attività non viene avviata per la prima volta.

Caso d'uso 3: nascondi parzialmente l'attività

Hai appreso che, quando viene avviata un'app e viene chiamato il numero onStart(), l'app diventa visibile sullo schermo. Quando l'app viene ripristinata e onResume() viene chiamato, l'app ottiene lo stato attivo dell'utente. La parte del ciclo di vita in cui l'app è interamente sullo schermo e ha come target l'utente è il ciclo di vita interattivo.

Quando l'app passa in background, lo stato attivo viene perso dopo onPause() e l'app non è più visibile dopo onStop().

La differenza tra focus e visibilità è importante perché un'attività può essere parzialmente visibile sullo schermo, ma non mettere a fuoco l'utente. In questo passaggio, osserviamo un caso in cui un'attività è parzialmente visibile, ma non incentrata sull'utente.

  1. Con l'app DessertClicker in esecuzione, fai clic sul pulsante Condividi in alto a destra dello schermo.




    L'attività di condivisione viene visualizzata nella metà inferiore dello schermo, ma resta visibile nella metà superiore.
  2. Esamina Logcat e nota che solo onPause() è stato chiamato.


    In questo caso d'uso, onStop() non viene chiamato perché l'attività è ancora parzialmente visibile. Tuttavia, l'attività non è incentrata sull'utente e l'utente non può interagirvi. L'attività "in primo piano" è in primo piano per gli utenti.

    Perché questa differenza è importante? Prendi in considerazione l'app di fisica. Potresti voler interrompere la simulazione quando l'app è in background e continuare a essere eseguita quando l'app è parzialmente oscurata. In questo caso, interromperai la simulazione in onStop(). Se vuoi che la simulazione si interrompa quando l'attività è oscurata parzialmente, devi inserire il codice per interrompere la simulazione in onPause().

    Qualsiasi codice in esecuzione in onPause() blocca la visualizzazione di altri elementi, quindi mantieni il codice in onPause() leggero. Ad esempio, se arriva una telefonata, il codice in onPause() potrebbe ritardare la notifica di chiamata in arrivo.
  3. Fai clic all'esterno della finestra di dialogo Condividi per tornare all'app e nota che è stato chiamato onResume().

    Sia onResume() che onPause() hanno a che fare con l'elemento attivo. Il metodo onResume() viene chiamato quando l'attività è attiva e onPause() viene chiamato quando l'attività perde la concentrazione.

Il ciclo di vita dei frammenti Android è simile al ciclo di vita delle attività e offre diversi metodi specifici.

In questa attività, puoi esaminare l'app AndroidTrivia che hai creato nei codelab precedenti e aggiungere alcuni log per esplorare il ciclo di vita dei frammenti. L'app AndroidTrivia ti consente di rispondere a domande sullo sviluppo di Android; se rispondi correttamente a tre di fila, vinci il gioco.

Ogni schermata nell'app AndroidTrivia è di tipo Fragment.

Per semplificare le cose, usa l'API Android Logging in questa attività anziché la libreria Timber.

  1. Apri l'app AndroidTrivia dall'ultimo codelab o scarica il codice della soluzione AndroidTrivia da GitHub.
  2. Apri il file TitleFragment.kt. Tieni presente che Android Studio potrebbe mostrare errori di associazione ed errori di riferimento non risolti finché non ricrei l'app.
  3. Scorri verso il basso fino al metodo onCreateView(). Noterai che qui il layout del frammento si gonfia e si verifica l'associazione di dati.
  4. Aggiungi un'istruzione di logging al metodo onCreateView(), tra la riga e setHasOptionsMenu() e la chiamata finale da restituire:
setHasOptionsMenu(true)

Log.i("TitleFragment", "onCreateView called")

return binding.root
  1. Appena sotto il metodo onCreateView(), aggiungi istruzioni di logging per ognuno dei metodi del ciclo di vita dei frammenti rimanenti. Ecco il codice:
override fun onAttach(context: Context?) {
   super.onAttach(context)
   Log.i("TitleFragment", "onAttach called")
}
override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   Log.i("TitleFragment", "onCreate called")
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
   super.onActivityCreated(savedInstanceState)
   Log.i("TitleFragment", "onActivityCreated called")
}
override fun onStart() {
   super.onStart()
   Log.i("TitleFragment", "onStart called")
}
override fun onResume() {
   super.onResume()
   Log.i("TitleFragment", "onResume called")
}
override fun onPause() {
   super.onPause()
   Log.i("TitleFragment", "onPause called")
}
override fun onStop() {
   super.onStop()
   Log.i("TitleFragment", "onStop called")
}
override fun onDestroyView() {
   super.onDestroyView()
   Log.i("TitleFragment", "onDestroyView called")
}
override fun onDetach() {
   super.onDetach()
   Log.i("TitleFragment", "onDetach called")
}
  1. Compila ed esegui l'app, quindi apri Logcat.
  2. Digita I/TitleFragment nel campo di ricerca per filtrare il log. All'avvio dell'app, Logcat avrà un aspetto simile al seguente screenshot:

Qui puoi vedere l'intero ciclo di vita di avvio del frammento, inclusi questi callback:

  • onAttach(): richiamato quando il frammento è associato alla sua attività proprietario.
  • onCreate(): in modo simile a onCreate() per l'attività, onCreate() per il frammento viene chiamato per creare un frammento iniziale (diverso dal layout).
  • onCreateView(): richiamato per gonfiare il layout del frammento.
  • onActivityCreated(): chiamato quando viene completata la onCreate() dell'attività del proprietario. Il tuo frammento non potrà accedere all'attività fino a quando questo metodo non viene chiamato.
  • onStart(): richiamato quando il frammento diventa visibile; parallelo al onStart() dell'attività.
  • onResume(): chiamato quando il frammento acquisisce l'attenzione dell'utente; parallelo al onResume() dell'attività.
  1. Tocca il pulsante Gioca per passare al gioco a quiz e nota subito il logcat.

L'apertura del frammento successivo causa la chiusura del frammento del titolo e la chiamata di questi metodi del ciclo di vita:

  • onPause(): richiamato quando il frammento perde l'attenzione dell'utente; parallelo al onPause() dell'attività.
  • onStop(): chiamato quando il frammento non è più visibile sullo schermo; parallelo al onStop() dell'attività.
  • onDestroyView(): chiamato quando la vista di frammenti non è più necessaria, per pulire le risorse associate a quella vista.
  1. Nell'app, tocca il pulsante Su (la freccia nell'angolo in alto a sinistra dello schermo) per tornare al frammento del titolo.


    Questa volta, onAttach() e onCreate() probabilmente non sono chiamati per iniziare il frammento. L'oggetto frammento esiste ancora e viene associato alla sua attività proprietario, quindi il ciclo di vita ricomincia con onCreateView().
  2. Premi il pulsante Home del dispositivo. Noterai che nel logcat vengono chiamati solo onPause() e onStop(). Questo è lo stesso comportamento dell'attività: il ritorno alla home page mette l'attività e il frammento in background.
  3. Usa la schermata recente per tornare all'app. Come nell'attività, vengono chiamati i metodi onStart() e onResume() per restituire il frammento in primo piano.

Progetto Android Studio: DessertClickerLogs

Ciclo di vita delle attività

  • Il ciclo di vita delle attività è un insieme di stati in cui viene eseguita un'attività. Il ciclo di vita dell'attività inizia quando l'attività viene creata per la prima volta e termina quando viene eliminata.
  • Quando l'utente si sposta tra le attività e all'interno e all'esterno della tua app, ogni attività si sposta tra gli stati nel ciclo di vita delle attività.
  • Ogni stato nel ciclo di vita dell'attività ha un metodo di callback corrispondente che puoi sostituire nella tua classe Activity. Esistono sette metodi del ciclo di vita:
    onCreate()
    onStart()
    onPause()
    onRestart()
    onResume()
    onStop()
    onDestroy()
  • Per aggiungere un comportamento che si verifica quando l'attività passa a uno stato di ciclo di vita, esegui l'override del metodo di callback dello stato.
  • Per aggiungere metodi di sostituzione degli schemi ai tuoi corsi in Android Studio, seleziona Codice > Metodi di sostituzione o premi Control+o.

Log con il log

  • L'API di logging di Android, in particolare la classe Log, ti consente di scrivere brevi messaggi che vengono visualizzati in Logcat all'interno di Android Studio.
  • Utilizza Log.i() per scrivere un messaggio informativo. Questo metodo prevede due argomenti: il tag tag, in genere il nome della classe, e il messaggio messaggio, una breve stringa.
  • Usa il riquadro Logcat in Android Studio per visualizzare i log di sistema, inclusi i messaggi che scrivi.

Registrazione con legno

Timber è una libreria di logging con diversi vantaggi rispetto all'API Android Logging. In particolare, la libreria di Timber:

  • Genera il tag di log per te in base al nome della classe.
  • Consente di evitare di mostrare i log in una versione di release dell'app Android.
  • Consente l'integrazione con librerie di report sugli arresti anomali.

Per utilizzare Timber, aggiungi la relativa dipendenza al file Gradle ed estendi la classe Application per inizializzarla:

  • Application è una classe base che contiene lo stato dell'applicazione globale per l'intera app. Esiste una classe Application predefinita utilizzata da Android se non ne specifichi una. Puoi creare una sottoclasse Application per inizializzare le librerie a livello di app, ad esempio Timber.
  • Aggiungi la classe Application personalizzata alla tua app aggiungendo l'attributo android:name all'elemento <application> nel file manifest Android. Non dimenticare di farlo!
  • Utilizza Timber.i() per scrivere messaggi di log con Timber. Questo metodo richiede solo un argomento: il messaggio da scrivere. Il tag di log (il nome della classe) viene aggiunto automaticamente.

Corso Udacity:

Documentazione per gli sviluppatori Android:

Altro:

In questa sezione sono elencati i possibili compiti per gli studenti che lavorano attraverso questo codelab nell'ambito di un corso tenuto da un insegnante. Spetta all'insegnante fare quanto segue:

  • Assegna i compiti, se necessario.
  • Comunica agli studenti come inviare compiti.
  • Valuta i compiti.

Gli insegnanti possono utilizzare i suggerimenti solo quanto e come vogliono e dovrebbero assegnare i compiti che ritengono appropriati.

Se stai lavorando da solo a questo codelab, puoi utilizzare questi compiti per mettere alla prova le tue conoscenze.

Cambiare un'app

Apri l'app DiceRoller della lezione 1. Se non hai l'app, scaricala qui. Aggiungi il supporto Timber all'app, seguendo la stessa procedura utilizzata per l'app DessertClicker. Sostituisci tutti i callback del ciclo di vita e aggiungi messaggi di logging per ogni callback.

Rispondi a queste domande

Domanda 1

Quale tra i seguenti NON è uno stato del ciclo di vita delle attività?

  • Ora avvio
  • In attesa
  • Creata
  • Eliminata

Domanda 2

Quale metodo del ciclo di vita viene chiamato per rendere visibile un'attività?

  • onPause()
  • onVisible()
  • onStart()
  • onDestroy()

Domanda 3

Quale metodo del ciclo di vita viene chiamato per concentrare l'attività?

  • onResume()
  • onVisible()
  • onStart()
  • onFocus()

Domanda 4

Quando viene chiamata l'attività onCreate()?

  • Ogni volta che l'attività è visibile all'utente.
  • Ogni volta che l'attività torna in background.
  • Solo una volta, quando l'attività è creata.
  • Solo una volta, quando l'attività viene ripresa.

Inviare l'app per la valutazione

Verifica che l'app contenga quanto segue:

  • Una dipendenza a Timber nel file build.gradle per l'app.
  • Una sottoclasse personalizzata di Application che inizializza Timber in onCreate().
  • Un attributo per quella sottoclasse personalizzata nel manifest Android.
  • I metodi vengono sostituiti in MainActivity per tutti i metodi di callback del ciclo di vita e le chiamate a Timber.i() per il logging.

Inizia la lezione successiva: 4.2: Situazioni complesse del ciclo di vita

Per i link ad altri codelab in questo corso, consulta la pagina di destinazione di Android Kotlin Fundamentals.