Ciclo di vita dell'attività

Le attività sono un blocco predefinito fondamentale delle applicazioni Android e possono esistere in diversi stati. Il ciclo di vita dell'attività inizia con la creazione di istanze e termina con la distruzione e include molti stati tra di loro. Quando un'attività cambia stato, viene chiamato il metodo di evento del ciclo di vita appropriato, notificando l'attività della modifica dello stato in sospeso e consentendo l'esecuzione del codice per adattarsi a tale modifica. Questo articolo esamina il ciclo di vita delle attività e spiega la responsabilità che un'attività ha durante ognuna di queste modifiche di stato per far parte di un'applicazione affidabile e ben comportata.

Panoramica del ciclo di vita delle attività

Le attività sono un concetto di programmazione insolito specifico per Android. Nello sviluppo di applicazioni tradizionali è in genere presente un metodo main statico, che viene eseguito per avviare l'applicazione. Con Android, tuttavia, le cose sono diverse; Le applicazioni Android possono essere avviate tramite qualsiasi attività registrata all'interno di un'applicazione. In pratica, la maggior parte delle applicazioni avrà solo un'attività specifica specificata come punto di ingresso dell'applicazione. Tuttavia, se un'applicazione si arresta in modo anomalo o viene terminata dal sistema operativo, il sistema operativo può provare a riavviare l'applicazione nell'ultima attività aperta o in qualsiasi altro punto all'interno dello stack di attività precedente. Inoltre, il sistema operativo può sospendere le attività quando non sono attive e recuperarle se la memoria è insufficiente. È necessario prendere attentamente in considerazione per consentire all'applicazione di ripristinare correttamente lo stato nel caso in cui un'attività venga riavviata, soprattutto se tale attività dipende dai dati delle attività precedenti.

Il ciclo di vita dell'attività viene implementato come raccolta di metodi che il sistema operativo chiama per tutto il ciclo di vita di un'attività. Questi metodi consentono agli sviluppatori di implementare le funzionalità necessarie per soddisfare i requisiti di gestione dello stato e delle risorse delle applicazioni.

È estremamente importante per lo sviluppatore di applicazioni analizzare i requisiti di ogni attività per determinare quali metodi esposti dal ciclo di vita dell'attività devono essere implementati. In caso contrario, può verificarsi un'instabilità dell'applicazione, arresti anomali, bloat delle risorse e possibilmente anche l'instabilità del sistema operativo sottostante.

Questo capitolo esamina in dettaglio il ciclo di vita delle attività, tra cui:

  • Stati attività
  • Metodi del ciclo di vita
  • Mantenimento dello stato di un'applicazione

Questa sezione include anche una procedura dettagliata che fornisce esempi pratici su come salvare in modo efficiente lo stato durante il ciclo di vita dell'attività. Al termine di questo capitolo è necessario conoscere il ciclo di vita dell'attività e come supportarlo in un'applicazione Android.

Ciclo di vita dell'attività

Il ciclo di vita dell'attività Android include una raccolta di metodi esposti all'interno della classe Activity che forniscono allo sviluppatore un framework di gestione delle risorse. Questo framework consente agli sviluppatori di soddisfare i requisiti univoci di gestione dello stato di ogni attività all'interno di un'applicazione e di gestire correttamente la gestione delle risorse.

Stati attività

Il sistema operativo Android arbitra le attività in base al relativo stato. Ciò consente ad Android di identificare le attività che non sono più in uso, consentendo al sistema operativo di recuperare memoria e risorse. Il diagramma seguente illustra gli stati che un'attività può attraversare durante la sua durata:

Activity states diagram

Questi stati possono essere suddivisi in 4 gruppi principali come indicato di seguito:

  1. Attivo o In esecuzione : le attività vengono considerate attive o in esecuzione se sono in primo piano, note anche come la parte superiore dello stack di attività. Questa operazione viene considerata l'attività con priorità più alta in Android e, di conseguenza, verrà terminata solo dal sistema operativo in situazioni estreme, ad esempio se l'attività tenta di usare più memoria di quanto sia disponibile nel dispositivo, in quanto ciò potrebbe causare la mancata risposta dell'interfaccia utente.

  2. Sospeso : quando il dispositivo passa alla sospensione o un'attività è ancora visibile ma parzialmente nascosta da una nuova attività non completa o trasparente, l'attività viene considerata sospesa. Le attività sospese sono ancora attive, ovvero mantengono tutte le informazioni sullo stato e sui membri e rimangono associate al gestore finestre. Questa attività è considerata la seconda attività con priorità più alta in Android e, di conseguenza, verrà terminata dal sistema operativo solo se l'eliminazione di questa attività soddisfa i requisiti di risorse necessari per mantenere stabile e reattiva l'attività attiva/in esecuzione.

  3. Arrestato/In background : le attività completamente oscurate da un'altra attività vengono considerate arrestate o in background. Le attività arrestate tentano comunque di mantenere le informazioni sullo stato e sui membri per il più lungo tempo possibile, ma le attività arrestate sono considerate la priorità più bassa dei tre stati e, di conseguenza, il sistema operativo ucciderà le attività in questo stato per soddisfare prima i requisiti delle risorse delle attività con priorità più alta.

  4. Riavviato : è possibile che un'attività che si trovi in qualsiasi punto dalla sospensione all'arresto nel ciclo di vita venga rimossa dalla memoria da Android. Se l'utente torna all'attività che deve essere riavviata, ripristinata allo stato salvato in precedenza e quindi visualizzata all'utente.

Ricreazione dell'attività in risposta alle modifiche alla configurazione

Per rendere più complicato, Android genera un'altra chiave nella combinazione denominata Modifiche di configurazione. Le modifiche alla configurazione sono cicli rapidi di distruzione/ricreazione delle attività che si verificano quando viene modificata la configurazione di un'attività, ad esempio quando il dispositivo viene ruotato (e l'attività deve essere ricreata in modalità orizzontale o verticale), quando viene visualizzata la tastiera (e l'attività viene visualizzata con l'opportunità di ridimensionarsi) o quando il dispositivo viene posizionato in un dock, tra gli altri.

Le modifiche di configurazione causano comunque le stesse modifiche dello stato dell'attività che si verificherebbero durante l'arresto e il riavvio di un'attività. Tuttavia, per assicurarsi che un'applicazione si senta reattiva e funzioni correttamente durante le modifiche alla configurazione, è importante che vengano gestite il più rapidamente possibile. Per questo motivo, Android ha un'API specifica che può essere usata per rendere persistente lo stato durante le modifiche alla configurazione. Questo argomento verrà illustrato più avanti nella sezione Gestione dello stato durante tutto il ciclo di vita .

Metodi relativi al ciclo di vita delle attività

Android SDK e, per estensione, il framework Xamarin.Android offre un modello potente per la gestione dello stato delle attività all'interno di un'applicazione. Quando lo stato di un'attività cambia, l'attività viene notificata dal sistema operativo, che chiama metodi specifici per tale attività. Il diagramma seguente illustra questi metodi in relazione al ciclo di vita dell'attività:

Activity Lifecycle flowchart

Gli sviluppatori possono gestire le modifiche di stato eseguendo l'override di questi metodi all'interno di un'attività. È importante notare, tuttavia, che tutti i metodi del ciclo di vita vengono chiamati nel thread dell'interfaccia utente e impediranno al sistema operativo di eseguire il lavoro successivo dell'interfaccia utente, ad esempio nascondere l'attività corrente, visualizzare una nuova attività e così via. Di conseguenza, il codice in questi metodi deve essere il più breve possibile per rendere un'applicazione con prestazioni buone. Tutte le attività a esecuzione prolungata devono essere eseguite su un thread in background.

Esaminiamo ognuno di questi metodi del ciclo di vita e il relativo uso:

OnCreate

OnCreate è il primo metodo da chiamare quando viene creata un'attività. OnCreate viene sempre sottoposto a override per eseguire le inizializzazioni di avvio che possono essere richieste da un'attività, ad esempio:

  • Creazione di visualizzazioni
  • Inizializzazione delle variabili
  • Associazione di dati statici agli elenchi

OnCreate accetta un parametro Bundle , ovvero un dizionario per l'archiviazione e il passaggio di informazioni sullo stato e gli oggetti tra attività Se il bundle non è Null, indica che l'attività viene riavviata e deve ripristinarne lo stato dall'istanza precedente. Il codice seguente illustra come recuperare i valori dal bundle:

protected override void OnCreate(Bundle bundle)
{
   base.OnCreate(bundle);

   string intentString;
   bool intentBool;

   if (bundle != null)
   {
      intentString = bundle.GetString("myString");
      intentBool = bundle.GetBoolean("myBool");
   }

   // Set our view from the "main" layout resource
   SetContentView(Resource.Layout.Main);
}

Al OnCreate termine, Android chiamerà OnStart.

OnStart

OnStart viene sempre chiamato dal sistema al OnCreate termine. Le attività possono eseguire l'override di questo metodo se devono eseguire attività specifiche immediatamente prima che un'attività diventi visibile, ad esempio l'aggiornamento dei valori correnti delle visualizzazioni all'interno dell'attività. Android chiamerà OnResume immediatamente dopo questo metodo.

OnResume

Il sistema chiama OnResume quando l'attività è pronta per iniziare a interagire con l'utente. Le attività devono eseguire l'override di questo metodo per eseguire attività come:

  • Aumento delle frequenze dei fotogrammi (un'attività comune nello sviluppo di giochi)
  • Animazioni iniziali
  • Ascolto degli aggiornamenti GPS
  • Visualizzare eventuali avvisi o finestre di dialogo pertinenti
  • Collegare gestori eventi esterni

Ad esempio, il frammento di codice seguente mostra come inizializzare la fotocamera:

protected override void OnResume()
{
    base.OnResume(); // Always call the superclass first.

    if (_camera==null)
    {
        // Do camera initializations here
    }
}

OnResume è importante perché qualsiasi operazione eseguita in OnPause deve essere annullata in OnResume, poiché è l'unico metodo del ciclo di vita garantito per l'esecuzione dopo OnPause il ripristino dell'attività.

OnPause

OnPause viene chiamato quando il sistema sta per inserire l'attività in background o quando l'attività diventa parzialmente oscurata. Le attività devono eseguire l'override di questo metodo se necessario:

  • Eseguire il commit di modifiche non salvate ai dati persistenti

  • Eliminare o pulire altri oggetti che usano risorse

  • Riduzione delle frequenze dei fotogrammi e sospensione delle animazioni

  • Annullare la registrazione di gestori eventi esterni o gestori di notifica (ad esempio quelli associati a un servizio). Questa operazione deve essere eseguita per evitare perdite di memoria dell'attività.

  • Analogamente, se l'attività ha visualizzato finestre di dialogo o avvisi, è necessario eseguire la pulizia con il .Dismiss() metodo .

Ad esempio, il frammento di codice seguente rilascia la fotocamera, perché l'attività non può usarla durante la pausa:

protected override void OnPause()
{
    base.OnPause(); // Always call the superclass first

    // Release the camera as other activities might need it
    if (_camera != null)
    {
        _camera.Release();
        _camera = null;
    }
}

Esistono due possibili metodi del ciclo di vita che verranno chiamati dopo OnPause:

  1. OnResume verrà chiamato se l'attività deve essere restituita in primo piano.
  2. OnStop verrà chiamato se l'attività viene posizionata in background.

OnStop

OnStop viene chiamato quando l'attività non è più visibile all'utente. Ciò si verifica quando si verifica una delle operazioni seguenti:

  • È in corso l'avvio di una nuova attività che copre questa attività.
  • Un'attività esistente viene portata in primo piano.
  • L'attività viene distrutta.

OnStop potrebbe non essere sempre chiamato in situazioni di memoria insufficiente, ad esempio quando Android è affamato per le risorse e non può essere in background correttamente l'attività. Per questo motivo, è consigliabile non fare affidamento su OnStop come chiamare durante la preparazione di un'attività per la distruzione. I metodi del ciclo di vita successivi che possono essere chiamati dopo questa operazione saranno OnDestroy se l'attività è in uscita o OnRestart se l'attività torna a interagire con l'utente.

OnDestroy

OnDestroy è il metodo finale chiamato su un'istanza di Activity prima che venga eliminato e rimosso completamente dalla memoria. In situazioni estreme Android può terminare il processo dell'applicazione che ospita l'attività, che comporterà OnDestroy la mancata chiamata. La maggior parte delle attività non implementerà questo metodo perché la maggior parte delle operazioni di pulizia e arresto è stata eseguita nei OnPause metodi e OnStop . Il OnDestroy metodo viene in genere sottoposto a override per pulire le attività a esecuzione prolungata che potrebbero causare perdite di risorse. Un esempio di questo potrebbe essere costituito da thread in background avviati in OnCreate.

Non ci saranno metodi del ciclo di vita chiamati dopo che l'attività è stata eliminata definitivamente.

OnRestart

OnRestart viene chiamato dopo che l'attività è stata arrestata, prima che venga avviata di nuovo. Un buon esempio di questo problema è quando l'utente preme il pulsante Home mentre si usa un'attività nell'applicazione. Quando questo accade OnPause e quindi OnStop vengono chiamati i metodi e l'attività viene spostata in background, ma non viene eliminata definitivamente. Se l'utente dovesse quindi ripristinare l'applicazione usando gestione attività o un'applicazione simile, Android chiamerà il OnRestart metodo dell'attività.

Non esistono linee guida generali per il tipo di logica da implementare in OnRestart. Ciò è dovuto al fatto che OnStart viene sempre richiamato indipendentemente dal fatto che l'attività venga creata o riavviata, pertanto tutte le risorse richieste dall'attività devono essere inizializzate in OnStart, anziché OnRestart.

Il metodo del ciclo di vita successivo chiamato dopo OnRestart sarà OnStart.

Indietro e home

Molti dispositivi Android hanno due pulsanti distinti: un pulsante "Indietro" e un pulsante "Home". Un esempio può essere visualizzato nello screenshot seguente di Android 4.0.3:

Back and Home buttons

Esiste una sottile differenza tra i due pulsanti, anche se sembrano avere lo stesso effetto di inserire un'applicazione in background. Quando un utente fa clic sul pulsante Indietro, comunica ad Android che l'attività viene eseguita. Android eliminerà l'attività. Al contrario, quando l'utente fa clic sul pulsante Home, l'attività viene semplicemente inserita in background: Android non ucciderà l'attività.

Gestione dello stato durante tutto il ciclo di vita

Quando un'attività viene arrestata o eliminata definitivamente, il sistema offre l'opportunità di salvare lo stato dell'attività per una riattivazione successiva. Questo stato salvato viene definito stato dell'istanza. Android offre tre opzioni per l'archiviazione dello stato dell'istanza durante il ciclo di vita dell'attività:

  1. Archiviazione di valori primitivi in un Dictionarybundle che Android userà per salvare lo stato.

  2. Creazione di una classe personalizzata che conterrà valori complessi, ad esempio bitmap. Android userà questa classe personalizzata per salvare lo stato.

  3. Aggirare il ciclo di vita delle modifiche alla configurazione e assumere la responsabilità completa di mantenere lo stato nell'attività.

Questa guida illustra le prime due opzioni.

Stato bundle

L'opzione primaria per il salvataggio dello stato dell'istanza consiste nell'usare un oggetto dizionario chiave/valore noto come bundle. Tenere presente che quando viene creata un'attività che il OnCreate metodo viene passato come parametro, questo bundle può essere usato per ripristinare lo stato dell'istanza. Non è consigliabile usare un bundle per dati più complessi che non serializzeranno rapidamente o facilmente in coppie chiave/valore (ad esempio bitmap); piuttosto, deve essere usato per valori semplici come stringhe.

Un'attività fornisce metodi che consentono di salvare e recuperare lo stato dell'istanza nel bundle:

  • OnSaveInstanceState : viene richiamato da Android quando l'attività viene eliminata definitivamente. Le attività possono implementare questo metodo se devono rendere persistenti gli elementi di stato chiave/valore.

  • OnRestoreInstanceState : viene chiamato al termine del OnCreate metodo e offre un'altra opportunità per un'attività di ripristinare lo stato dopo il completamento dell'inizializzazione.

Il diagramma seguente illustra come vengono usati questi metodi:

Bundle states flowchart

OnSaveInstanceState

OnSaveInstanceState verrà chiamato quando l'attività viene arrestata. Riceverà un parametro bundle in cui l'attività può archiviarne lo stato. Quando un dispositivo subisce una modifica della configurazione, un'attività può usare l'oggetto passato per mantenere lo stato dell'attività eseguendo l'override Bundle di OnSaveInstanceState. Si consideri il codice di esempio seguente:

int c;

protected override void OnCreate (Bundle bundle)
{
  base.OnCreate (bundle);

  this.SetContentView (Resource.Layout.SimpleStateView);

  var output = this.FindViewById<TextView> (Resource.Id.outputText);

  if (bundle != null) {
    c = bundle.GetInt ("counter", -1);
  } else {
    c = -1;
  }

  output.Text = c.ToString ();

  var incrementCounter = this.FindViewById<Button> (Resource.Id.incrementCounter);

  incrementCounter.Click += (s,e) => {
    output.Text = (++c).ToString();
  };
}

Il codice precedente incrementa un numero intero denominato c quando si fa clic su un pulsante denominato incrementCounter , visualizzando il risultato in un TextView oggetto denominato output. Quando si verifica una modifica della configurazione, ad esempio quando il dispositivo viene ruotato, il codice precedente perde il valore di c perché è bundlenull, come illustrato nella figura seguente:

Display does not show previous value

Per mantenere il valore di c in questo esempio, l'attività può eseguire l'override OnSaveInstanceStatedi , salvando il valore nel bundle come illustrato di seguito:

protected override void OnSaveInstanceState (Bundle outState)
{
  outState.PutInt ("counter", c);
  base.OnSaveInstanceState (outState);
}

Ora quando il dispositivo viene ruotato su un nuovo orientamento, l'intero viene salvato nel bundle e viene recuperato con la riga:

c = bundle.GetInt ("counter", -1);

Nota

È importante chiamare sempre l'implementazione di base di OnSaveInstanceState in modo che sia possibile salvare anche lo stato della gerarchia di visualizzazione.

Visualizza stato

L'override OnSaveInstanceState è un meccanismo appropriato per salvare i dati temporanei in un'attività tra le modifiche di orientamento, ad esempio il contatore nell'esempio precedente. Tuttavia, l'implementazione predefinita di si occuperà di OnSaveInstanceState salvare i dati temporanei nell'interfaccia utente per ogni visualizzazione, purché a ogni visualizzazione sia assegnato un ID. Si supponga, ad esempio, che un'applicazione abbia un EditText elemento definito in XML come indicato di seguito:

<EditText android:id="@+id/myText"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"/>

Poiché il EditText controllo è id stato assegnato, quando l'utente immette alcuni dati e ruota il dispositivo, i dati vengono ancora visualizzati, come illustrato di seguito:

Data is preserved in landscape mode

OnRestoreInstanceState

OnRestoreInstanceState verrà chiamato dopo OnStart. Offre un'attività la possibilità di ripristinare qualsiasi stato salvato in precedenza in un bundle durante l'oggetto precedente OnSaveInstanceState. Si tratta dello stesso bundle fornito a OnCreate, tuttavia.

Il codice seguente illustra come ripristinare lo stato in OnRestoreInstanceState:

protected override void OnRestoreInstanceState(Bundle savedState)
{
    base.OnRestoreInstanceState(savedState);
    var myString = savedState.GetString("myString");
    var myBool = savedState.GetBoolean("myBool");
}

Questo metodo esiste per offrire una certa flessibilità quando deve essere ripristinato lo stato. In alcuni casi è più appropriato attendere che tutte le inizializzazioni vengano eseguite prima di ripristinare lo stato dell'istanza. Inoltre, una sottoclasse di un'attività esistente può voler ripristinare determinati valori solo dallo stato dell'istanza. In molti casi, non è necessario eseguire l'override OnRestoreInstanceStatedi , poiché la maggior parte delle attività può ripristinare lo stato usando il bundle fornito a OnCreate.

Per un esempio di salvataggio dello stato usando un Bundleoggetto , fare riferimento alla procedura dettagliata - Salvataggio dello stato dell'attività.

Limitazioni del bundle

Anche se OnSaveInstanceState semplifica il salvataggio dei dati temporanei, presenta alcune limitazioni:

  • Non viene chiamato in tutti i casi. Ad esempio, premendo Home o Indietro per uscire da un'attività non OnSaveInstanceState verrà chiamato.

  • Il bundle passato in OnSaveInstanceState non è progettato per oggetti di grandi dimensioni, ad esempio immagini. Nel caso di oggetti di grandi dimensioni, è preferibile salvare l'oggetto da OnRetainNonConfigurationInstance , come illustrato di seguito.

  • I dati salvati tramite il bundle vengono serializzati, che possono causare ritardi.

Lo stato del bundle è utile per dati semplici che non usano molta memoria, mentre i dati dell'istanza non di configurazione sono utili per dati più complessi o dati costosi da recuperare, ad esempio da una chiamata al servizio Web o da una query di database complessa. I dati dell'istanza non di configurazione vengono salvati in un oggetto in base alle esigenze. La sezione successiva illustra OnRetainNonConfigurationInstance come mantenere tipi di dati più complessi tramite modifiche alla configurazione.

Salvataggio permanente di dati complessi

Oltre a rendere persistenti i dati nel bundle, Android supporta anche il salvataggio dei dati eseguendo l'override di OnRetainNonConfigurationInstance e restituendo un'istanza di che Java.Lang.Object contiene i dati da salvare in modo permanente. Esistono due vantaggi principali dell'uso OnRetainNonConfigurationInstance di per salvare lo stato:

  • L'oggetto restituito da OnRetainNonConfigurationInstance offre prestazioni elevate con tipi di dati più grandi e più complessi perché la memoria mantiene questo oggetto.

  • Il OnRetainNonConfigurationInstance metodo viene chiamato su richiesta e solo quando necessario. Questo è più economico rispetto all'uso di una cache manuale.

L'uso OnRetainNonConfigurationInstance è adatto per scenari in cui è costoso recuperare i dati più volte, ad esempio nelle chiamate al servizio Web. Si consideri ad esempio il codice seguente che esegue la ricerca in Twitter:

public class NonConfigInstanceActivity : ListActivity
{
  protected override void OnCreate (Bundle bundle)
  {
    base.OnCreate (bundle);
    SearchTwitter ("xamarin");
  }

  public void SearchTwitter (string text)
  {
    string searchUrl = String.Format("http://search.twitter.com/search.json?" + "q={0}&rpp=10&include_entities=false&" + "result_type=mixed", text);

    var httpReq = (HttpWebRequest)HttpWebRequest.Create (new Uri (searchUrl));
    httpReq.BeginGetResponse (new AsyncCallback (ResponseCallback), httpReq);
  }

  void ResponseCallback (IAsyncResult ar)
  {
    var httpReq = (HttpWebRequest)ar.AsyncState;

    using (var httpRes = (HttpWebResponse)httpReq.EndGetResponse (ar)) {
      ParseResults (httpRes);
    }
  }

  void ParseResults (HttpWebResponse httpRes)
  {
    var s = httpRes.GetResponseStream ();
    var j = (JsonObject)JsonObject.Load (s);

    var results = (from result in (JsonArray)j ["results"] let jResult = result as JsonObject select jResult ["text"].ToString ()).ToArray ();

    RunOnUiThread (() => {
      PopulateTweetList (results);
    });
  }

  void PopulateTweetList (string[] results)
  {
    ListAdapter = new ArrayAdapter<string> (this, Resource.Layout.ItemView, results);
  }
}

Questo codice recupera i risultati dal Web formattato come JSON, li analizza e quindi presenta i risultati in un elenco, come illustrato nello screenshot seguente:

Results displayed on screen

Quando si verifica una modifica della configurazione, ad esempio quando un dispositivo viene ruotato, il codice ripete il processo. Per riutilizzare i risultati recuperati originariamente e non causare chiamate di rete inutili e ridondanti, è possibile usare OnRetainNonconfigurationInstance per salvare i risultati, come illustrato di seguito:

public class NonConfigInstanceActivity : ListActivity
{
  TweetListWrapper _savedInstance;

  protected override void OnCreate (Bundle bundle)
  {
    base.OnCreate (bundle);

    var tweetsWrapper = LastNonConfigurationInstance as TweetListWrapper;

    if (tweetsWrapper != null) {
      PopulateTweetList (tweetsWrapper.Tweets);
    } else {
      SearchTwitter ("xamarin");
    }

    public override Java.Lang.Object OnRetainNonConfigurationInstance ()
    {
      base.OnRetainNonConfigurationInstance ();
      return _savedInstance;
    }

    ...

    void PopulateTweetList (string[] results)
    {
      ListAdapter = new ArrayAdapter<string> (this, Resource.Layout.ItemView, results);
      _savedInstance = new TweetListWrapper{Tweets=results};
    }
}

Ora, quando il dispositivo viene ruotato, i risultati originali vengono recuperati dalla LastNonConfiguartionInstance proprietà . In questo esempio i risultati sono costituiti da un string[] tweet contenente. Poiché OnRetainNonConfigurationInstance richiede che venga restituito un Java.Lang.Object oggetto , viene eseguito il string[] wrapping in una classe che esegue la sottoclasse Java.Lang.Object, come illustrato di seguito:

class TweetListWrapper : Java.Lang.Object
{
  public string[] Tweets { get; set; }
}

Ad esempio, il tentativo di usare come TextView oggetto restituito da OnRetainNonConfigurationInstance perderà l'attività, come illustrato nel codice seguente:

TextView _textView;

protected override void OnCreate (Bundle bundle)
{
  base.OnCreate (bundle);

  var tv = LastNonConfigurationInstance as TextViewWrapper;

  if(tv != null) {
    _textView = tv;
    var parent = _textView.Parent as FrameLayout;
    parent.RemoveView(_textView);
  } else {
    _textView = new TextView (this);
    _textView.Text = "This will leak.";
  }

  SetContentView (_textView);
}

public override Java.Lang.Object OnRetainNonConfigurationInstance ()
{
  base.OnRetainNonConfigurationInstance ();
  return _textView;
}

In questa sezione si è appreso come mantenere i dati sullo stato semplice con Bundlee rendere persistenti tipi di dati più complessi con OnRetainNonConfigurationInstance.

Riepilogo

Il ciclo di vita delle attività Android offre un framework potente per la gestione dello stato delle attività all'interno di un'applicazione, ma può essere difficile da comprendere e implementare. Questo capitolo ha introdotto i diversi stati che un'attività può attraversare durante la sua durata, nonché i metodi del ciclo di vita associati a tali stati. Successivamente, sono state fornite indicazioni sul tipo di logica da eseguire in ognuno di questi metodi.