2011-01-03 4 views
20

Sono stato infastidito da questo per un po '. Come gestisco correttamente le modifiche all'orientamento dello schermo mentre ho un Thread/AsyncTask separato in esecuzione? Attualmente, hoGestisce l'orientamento dello schermo cambia quando ci sono AsyncTasks in esecuzione

android:configChanges="orientation|keyboard|keyboardHidden" 

nel mio AndroidManifest.xml, ma che è not really encouraged:

Nota: Utilizzando questo attributo deve essere evitato e utilizzato solo come ultima istanza. Leggere la sezione Gestione delle modifiche di runtime per ulteriori informazioni su come gestire correttamente un riavvio a causa di una modifica della configurazione.

Inoltre, nel 2.3 emulatore, funziona quando si passa a landscape, ma tornando alla portrait fallisce.

Ora, il motivo per cui utilizzo configChanges è perché quando l'utente cambia orientamento, potrei avere un AsyncTask in esecuzione, fare un po 'di traffico di rete e non voglio che si fermi.

C'è qualche altro modo per farlo, o c'è un modo per aggiustare 2.3 per tornare al ritratto?

che so di onRetainNonConfigurationInstance, ma non sono sicuro che sarebbe una buona idea di "salvare" l'istanza AsyncTask, soprattutto perché la classe che estende AsyncTask non è statica (in modo che è legata al Activity) - e deve essere, perché in onPostExecute() chiama i metodi dall'istanza Activity.

risposta

7

Ho avuto un problema simile al tuo e ci ho lavorato attorno implementando lo AsyncTask come parte di una classe che eredita dalla classe Application. Una classe Application è a disposizione tutto il tempo di vita dell'applicazione Quindi non dovete preoccuparvi del vostro AsyncTask ottenere interrotto a meno che l'intera applicazione sarà ucciso.

Per ricevere una notifica al termine dell'operazione, Activity deve implementare un'interfaccia che utilizza per registrarsi alla classe Application.

Quando l'applicazione viene distrutta a causa della rotazione dello schermo, è possibile annullare la registrazione del Activity dalla classe Application e registrarlo di nuovo quando viene ricreato. Se l'attività termina tra distruzione e ricreazione il risultato dell'operazione può essere memorizzata nella classe Application nel frattempo in modo che il Activity possibile verificare se l'attività è ancora in esecuzione o se il risultato è già disponibile quando viene ricreato.

Un altro vantaggio è che si ha accesso diretto al contesto delle applicazioni poiché la classe Application è una sottoclasse della classe Context.

+0

Molto bello, molto più semplice dell'implementazione di un 'Servizio'. Grazie. – Felix

+0

@Flo so che è passato un po 'di tempo dal post ma sto cercando di fare lo stesso, ma non capisco cosa intendi con "Per ricevere una notifica quando l'attività è terminata, l'attività deve implementare un'interfaccia che utilizza per registrarsi alla classe Application. " Qualche possibilità di un esempio? (Sono nuovo a java e android1) – Bex

+0

Spiacente, non ho un esempio di codice. Ma date un'occhiata a [il pattern degli osservatori] (http://stackoverflow.com/questions/2483644/rosetta-stone-observer-pattern) Spero che capirete cosa intendo con "register" (update()) e "notifica" (addObserver()). – Flo

0

Ho già visualizzato una domanda simile here.

Fondamentalmente è presente un example su come mettere in pausa/riprendere un AsynTask sulla rotazione del dispositivo. Tuttavia non si adatta ancora a tutti i casi (a volte non è possibile sospendere l'azione in sicurezza, come ad esempio la creazione di un nuovo utente su un server remoto). Per quei casi "non sicuri" che devi codificare in qualche modo, definirei un "framework" complicato. Vedrai che CommonsWare fornisce link github a quello.

+0

Quindi non c'è un modo (facile) per mantenere il 'AsyncTask' in esecuzione mentre il' Activity' viene riavviato. Bummer. Tuttavia, ho scoperto che il non-cambio-ritorno-ritratto è un problema di emulazione, poiché l'app delle impostazioni fa la stessa cosa. – Felix

Problemi correlati