Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Xamarin, il ciclo di vita di un'app

Imparare in che modo Xamarin.Forms gestisce il ciclo di vita di un'app mobile, indipendentemente dalla piattaforma su cui essa viene eseguita.
Imparare in che modo Xamarin.Forms gestisce il ciclo di vita di un'app mobile, indipendentemente dalla piattaforma su cui essa viene eseguita.
Link copiato negli appunti

In questa lezione analizzeremo la classe Application e vedremo come viene gestito il ciclo di vita di un'applicazione Xamarin.Forms.

La classe Application

La classe Application rappresenta la base di un'app cross-platform creata con Xamarin.Forms. Tale classe è contenuta nell'assembly Xamarin.Forms.Core, introdotto solo dalla versione 1.3 di Xamarin, e permette la definizione della prima pagina dell'app.

La classe si compone delle seguenti proprietà:

Proprietà Descrizione
Current È una proprietà statica che contiene un riferimento all'oggetto dell'applicazione.
MainPage Permette di settare la prima pagina dell'applicazione.
Properties È un dizionario che estende l'interfaccia IDictionary<string, object>, ed è utile per memorizzare dati da mantenere durante i cambi di stato dell'app.
Resources È un altro dizionario di tipo ResourceDictionary, composto da coppie chiave-valore, dove le chiavi sono di tipo string e i valori sono di tipo object e rappresentano gli oggetti da memorizzare. Permette quindi di impostare e recuperare risorse per l'oggetto corrente.

Tra queste proprietà, il dizionario Properties ricopre un ruolo importante. Generalmente, i dati salvati al suo interno sono dati utilizzati in combinazione con i metodi del ciclo di vita dell'app definiti dalla classe Application. Il dizionario permette di memorizzare solo dati di tipo primitivo (string, int, ecc) e, pertanto, qualsiasi tentativo di memorizzare dati di altri tipi, come List<string>, falliscono. Il dizionario è salvato automaticamente sul dispositivo, rendendo i suoi dati disponibili nel momento in cui l'app torna ad essere visibile sullo schermo. Ciononostante, si può salvare il dizionario in modo proattivo usando il metodo SavePropertiesAsync(), che lo salverà sul dispositivo in modo asincrono. Ciò risulta utile soprattutto a seguito di aggiornamenti importanti, evitando che eventi inattesi come il crash dell'app causino una mancata serializzazione dei dati.

Come anticipato, oltre alla definizione di queste proprietà, la classe Application definisce ed espone anche i metodi per gestire il ciclo di vita dell'app, ossia: OnStart, OnSleep e OnResume.

Esaminiamo ora il costruttore della classe App del progetto HelloXamarin (Portatile).

public class App : Application
	{
		public App()
		{
			// The root page of your application
			MainPage = new ContentPage
			{
				Content = new StackLayout
				{
					VerticalOptions = LayoutOptions.Center,
					Children = {
						new Label {
							HorizontalTextAlignment = TextAlignment.Center,
							Text = "Hello Xamarin!"
						}
					}
				}
			};
		}
		//...
	}

Possiamo notare due aspetti fondamentali:

  • la visibilità della classe è pubblica;
  • la classe estende Application.

In questo modo la classe App è visibile dai progetti di ogni piattaforma e può, attraverso il suo costruttore, inizializzare la proprietà MainPage della classe Application ad un oggetto ContentPage di tipo Page. Un oggetto Page è l'analogo di una Activity in Android, un ViewController in iOS e una Page in Windows Phone. Il codice autogenerato con la creazione del progetto mostrerà una Label posizionata all'interno di uno StackLayout e centrata al suo interno. Infine, grazie all'estensione della classe Application, la classe App ci permette di sovrascrivere e di definire il comportamento dell'app nei suoi diversi stati.

Ciclo di vita di un'app

Chi ha una conoscenza basilare dello sviluppo di app per piattaforme mobili sa che è possibile gestire il ciclo di vita di un'applicazione e delle relative pagine attraverso l'impiego di opportuni metodi. Questi ultimi permettono di modificare il comportamento dell'applicazione al verificarsi di determinati eventi, come l'arrivo di una chiamata o più semplicemente lo spegnimento dello schermo.
Gli stati in cui si può trovare un'app sono essenzialmente quattro, come riportato nella figura seguente.

Figura 32. Schema del ciclo di vita di un'app Xamarin.Forms (click per ingrandire)

Schema del ciclo di vita di un'app Xamarin.Forms

La tabella seguente descrive il significato di ognuno degli stati appena illustrati.

Stato Descrizione
Not Running L'app non è stata ancora avviata
Running L'app è in esecuzion e visibile sullo schermo
Pause/Inactive L'app è interrotta da qualche evento esterno
Backgrounded L'app è in background (non visibile sullo schermo), ma sta comunque svolgendo delle operazioni
Idle/Suspended Se l'app non sta eseguendo alcuna operazione viene sospesa dal sistema operativo, che manterrà in vita il processo dell'app

Le piattaforme Android, iOS e Windows Phone offrono una gestione articolata del ciclo di vita di una pagina, dalla sua creazione fino alla sua distruzione, come riportato nella figura seguente.

Figura 33. Ciclo di vita di: (a) Activity di Android, (b) View Controller di iOS, e (c) una Page di Windows Phone (click per ingrandire).

Ciclo di vita di: (a) Activity di Android, (b) View Controller di iOS, e (c) una Page di Windows Phone

Al contrario, in Xamarin.Forms il ciclo di vita è definito attraverso i seguenti tre metodi:

Metodo Descrizione
OnStart È chiamato quando l'app è inizializzata
OnSleep È richiamato quando l'app viene sospesa ed è in background
OnResume È chiamato quando l'app è nuovamente in foreground dopo essere stata messa in background

È interessante notare che:

  • la creazione di una pagina è effettuata attraverso il costruttore della pagina, come precedentemente mostrato nel costruttore App();
  • non c'è un metodo di terminazione, che viene gestita a partire dal metodo OnSleep.

Il metodo OnSleep è, infatti, l'ultimo metodo chiamato prima della fine dell'esecuzione dell'app, e dopo la sua chiamata non abbiamo alcuna notifica che ci avverta di un'imminente terminazione dell'app. Ad esempio: se l'utente sta spegnendo il telefono mentre la nostra app è in esecuzione, prima dello spegnimento verrà invocato il metodo OnSleep a cui seguirà la terminazione. Ovviamente, questa regola non vale nei casi in cui l'app crasha a causa di comportamenti inaspettati.

Vediamo in azione il ciclo di vita della nostra app e modifichiamo il codice della classe App come segue:

public class App : Application
	{
		public App()
		{
			//Lasciare inalterato il codice della pagina
		}
		protected override void OnStart()
		{
			Debug.WriteLine("HelloXamarin OnStart");
		}
		protected override void OnSleep()
		{
			Debug.WriteLine("HelloXamarin OnSleep");
		}
		protected override void OnResume()
		{
			Debug.WriteLine("HelloXamarin OnResume");
		}
	}

A questo punto, compiliamo e lanciamo l'app sull'emulatore di una delle piattaforme di destinazione della nostra soluzione, ad esempio Android, e facciamo attenzione a quanto verrà riportato nella finestra Output, alla voce Debug. Quando l'app è visibile sullo schermo, nella finestra di Output potremmo leggere HelloXamarin OnStart a seguito della chiamata al metodo OnStart. Cliccando invece sul tasto Back verrà invocato il metodo OnSleep, l'app andrà in background e leggeremo HelloXamarin OnSleep nella finestra di Output. Infine, riportando in foreground l'app, viene richiamato il metodo OnResume e verrà visualizzata la scritta HelloXamarin OnResume.

Di seguito è possibile vedere il risultato finale della finestra di Output.

Figura 34. Output dell'esecuzione dell'app (click per ingrandire)

Output dell'esecuzione dell'app

In conclusione, per avere un'idea di come utilizzare la proprietà Properties di Application con i cambi di stato dell'app, modifichiamo il codice dei metodi OnSleep e OnResume come segue:

protected override void OnSleep()
	{
		Application.Current.Properties["test"] = "HTML.it";
		Debug.WriteLine("HelloXamarin OnSleep");
	}
	protected override void OnResume()
	{
		if (Application.Current.Properties.ContainsKey("test"))
		{
			string test = Application.Current.Properties["test"] as string;
			Debug.WriteLine(test);
			// do something with id
		}
		Debug.WriteLine("HelloXamarin OnResume");
	}

Eseguendo l'app sull'emulatore e riportandola in foreground potremo leggere nella finestra di Output la scritta “HTML.it” e che tale valore è stato correttamente salvato all'interno del dizionario con la chiave “test” per poter essere successivamente riutilizzato nel metodo OnResume attraverso il Debug.Writeline().

Figura 35. Output che mostra il corretto funzionamento dei metodi OnSleep e OnResume (click per ingrandire)

Output che mostra il corretto funzionamento dei metodi OnSleep e OnResume

Ti consigliamo anche