2011-01-03 13 views
20

Me han molestado por esto por un tiempo. ¿Cómo manejo adecuadamente los cambios de orientación de la pantalla mientras tengo un Thread/AsyncTask separado ejecutándose? Actualmente, tengoLa orientación de la pantalla del controlador cambia cuando hay AsyncTasks en ejecución

android:configChanges="orientation|keyboard|keyboardHidden" 

en mi AndroidManifest.xml, pero eso es not really encouraged:

Nota: El uso de este atributo debe ser evitado y utilizarse únicamente como último recurso. Lea la sección Manejo de los cambios de tiempo de ejecución para obtener más información sobre cómo manejar adecuadamente un reinicio debido a un cambio en la configuración.

Además, en el 2.3 emulador, funciona al cambiar a landscape, pero cambiar de nuevo a portrait falla.

Ahora, la razón por la que uso configChanges es porque cuando el usuario cambia de orientación, es posible que tenga un AsyncTask ejecutándose, haciendo algo de tráfico de red, y no quiero que se detenga.

¿Hay alguna otra forma de hacerlo, o hay una forma de arreglar 2.3 para volver al retrato?

que sé sobre onRetainNonConfigurationInstance, pero no estoy seguro de que sería una buena idea para "salvar" a la instancia AsyncTask, sobre todo porque la clase que se extiende AsyncTask no es estática (por lo que está ligado a la Activity) - y debe serlo, porque en onPostExecute() llama a los métodos de la instancia Activity.

Respuesta

7

Tuve un problema similar al tuyo y lo solucioné implementando el AsyncTask como parte de una clase que hereda de la clase Application. Una clase Application está disponible todo el tiempo de vida de la aplicación. Por lo tanto, no tiene que preocuparse por la interrupción de su AsyncTask a menos que se elimine toda la aplicación.

Para recibir una notificación cuando la tarea ha finalizado, el Activity tiene que implementar una interfaz que utiliza para registrarse en la clase Application.

Cuando se destruye su aplicación debido a la rotación de la pantalla, puede anular el registro de su Activity de la clase Application y volver a registrarla cuando se vuelva a crear. Si la tarea finaliza entre destrucción y recreación, el resultado de la operación puede almacenarse en la clase Application mientras tanto, para que el Activity pueda verificar si la tarea aún está en ejecución o si el resultado ya está disponible cuando se vuelva a crear.

Otra ventaja es que tiene acceso directo al contexto de las aplicaciones porque la clase Application es una subclase de la clase Context.

+0

Muy agradable, mucho más simple que implementar un 'Servicio'. Gracias. – Felix

+0

@Flo Sé que esto ha pasado un tiempo desde la publicación, pero estoy tratando de hacer lo mismo, pero no entiendo muy bien a qué te refieres con "Para recibir una notificación cuando la tarea haya terminado, la Actividad tiene que implementar una interfaz que usa para registrarse en la clase de Aplicación ". ¿Alguna posibilidad de un ejemplo? (Soy nuevo en java y android1) – Bex

+0

Lo siento, no tengo un ejemplo de código. Pero eche un vistazo a [el patrón de observador] (http://stackoverflow.com/questions/2483644/rosetta-stone-observer-pattern) Espero que entiendan a qué me refiero con "register" (update()) y "notificar" (addObserver()). – Flo

0

Ya he aparecido una pregunta similar here.

Básicamente hay un example de cómo pausar/reanudar un AsynTask en la rotación del dispositivo. Sin embargo, todavía no se ajusta a todos los casos (a veces no es posible suspender la acción de forma segura, como la creación de un nuevo usuario en un servidor remoto). Para esos casos "inseguros" necesitas codificar un poco, yo llamaría un "marco" complicado. Verá que CommonsWare le da enlaces a github.

+0

Así no hay manera (fácil) para mantener el 'AsyncTask' corriendo mientras que el' Activity' se está reiniciando. Gorrón. Sin embargo, descubrí que la opción de no volver a retratar es un problema de emulador, ya que la aplicación de configuración hace lo mismo. – Felix

Cuestiones relacionadas