2013-02-04 12 views
7

Caso d'uso:cambiamento dell'orientamento maniglia con l'esecuzione AsyncTask

L'utente avvia l'applicazione che caricherà un captcha. L'utente riempie il captcha e prova a scaricare alcune informazioni.

Problema:

Se l'utente ruotare il dispositivo durante il download del Activity è distrutto. Alla fine dell'esecuzione, AsyncTask sta tentando di aggiornare il Activity distrutto e il risultato è un "Visualizza non collegato al gestore di finestre".

soluzione "Wrong":

posso mascherare il problema con un android:configChanges="orientation|keyboardHidden|screenSize" ma con questo il layout non sta per essere aggiornato al paesaggio.

Quello che sto chiedendo:

E 'possibile modificare l'orientamento e cambiare il "riferimento" del Contesto passato al AsyncTask?

Questo answer suggerisce di verificare se la finestra di dialogo non è nullo, ma non è quello che sto cercando.

Here Egli suggerisce di usare un WeakReference (here un bel frammento su come usarlo), ma non ho capito se è quello che sto cercando.

Per essere più espliciti questo è quello che sto facendo nella OnPostExecute:

@Override 
protected void onPostExecute(Auto result) { 
    progress.dismiss(); 
    new DownloaderCaptcha(context).execute(""); 
    ((EditText)context.findViewById(R.id.editTextCaptcha)).setText(""); 
    context.findViewById(R.id.progrBar).setVisibility(View.VISIBLE); 
    context.findViewById(R.id.captcha).setVisibility(View.INVISIBLE); 

    if(result != null) { 
     Storage.storeHistory(context, result.getTarga().getValue()); 

     Intent i = new Intent(context, MenuActivity.class); 
     i.putExtra("result", result); 
     context.startActivity(i); 
    } else { 
     ErrorDialog.show(context, error); 
    } 
} 
+0

Non è la risposta migliore ma è possibile mantenere un riferimento sul proprio asyncTask e passarlo all'attività del paesaggio. L'attività orizzontale aggiornerebbe quindi il contesto asynctask ... Ma non so cosa succederà se il tuo ascncTask finirà durante la transizione di attività (ma ci sono soluzioni semplici a questo problema). – Xval

+0

@matiash: non c'è bisogno di downvotare, anche perché se si guarda il momento in cui è stata postata la risposta, è stato subito dopo che Alex ha postato questo! Quindi al momento non c'era una buona risposta alla mia domanda. Ovviamente puoi contrassegnarlo come un duplicato, ma un downvote è una mancanza di ricerca, non il mio caso, immagino. Solo i miei due centesimi. – Enrichman

+0

@Enrichman Non l'ho svalutato. Sono d'accordo che è una buona domanda, è solo una copia. – matiash

risposta

15

Ecco i miei consigli:

  • fare non uso android:configChanges per risolvere questo problema.

  • Do non utilizzare Activity#onRetainNonConfigurationInstance() per indirizzarlo (dato che questo approccio è deprecato).

  • Invece, utilizzare un lavoratore conservato Fragment. Ho recentemente posted an article che descrive come gestire le modifiche alla configurazione utilizzando il valore mantenuto Fragment s. Risolve il problema di mantenere un AsyncTask attraverso un cambio di rotazione piacevolmente. Fondamentalmente è necessario ospitare il numero all'interno di uno Fragment, chiamare lo setRetainInstance(true) su Fragment e segnalare lo stato/i risultati dello AsyncTask al suo Activity tramite il numero Fragment trattenuto.

+1

Sto riscontrando alcuni problemi nel tentativo di implementarlo ma immagino sia la soluzione migliore. Grazie. :) – Enrichman

+0

Mi piace così tanto questa risposta. :) – Alex

0

soluzione "Wrong":

posso mascherare il problema con un Android: configChanges =" orientation | keyboardHidden | screenSize "ma con questo layout non verrà aggiornato in orizzontale.

In realtà lo farà.

Android: configurazione configChanges elencate le modifiche che l'attività gestirà stessa. Quando si verifica una modifica alla configurazione in fase di esecuzione, l'attività viene arrestata e riavviata per impostazione predefinita, ma la dichiarazione di una configurazione con questo attributo impedirà il riavvio dell'attività a . Invece, l'attività rimane in esecuzione e viene chiamato il suo metodo onConfigurationChanged().

Date un'occhiata a http://developer.android.com/guide/topics/manifest/activity-element.html#config

È possibile implementare il layout per entrambe le modalità orizzontale e verticale o per annullare l'AsyncTask sulla modifica della configurazione.

+0

Certo che ho. Cambierà l'orientamento ma il layout utilizzato è quello definito per la modalità verticale. – Enrichman

+0

Ho aggiornato la risposta. – EvZ