studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones android multithreading orientation fragment

para - manual de programacion android pdf



La mejor práctica para manejar el cambio de orientación: Android (6)

Estaba pasando por varias prácticas para manejar el cambio de orientación con hilos y AsyncTask. Encontré las siguientes soluciones:

  1. Adjuntar-separar modelo: adjuntar y separar la actividad a los hilos y AsyncTask conservando su instancia. (Fuente: 1 , 2 )

  2. Fragmento sin cabeza: uso de un fragmento sin UI / sin cabeza para realizar todas las operaciones relacionadas con el hilo y conservar su instancia en el cambio de configuración. (Fuente: 1 , 2 )

¿Hay algún otro enfoque para manejar este escenario? ¿Cuál es la práctica recomendada? Pregunto esto porque no pude encontrar una solución genérica en ningún lugar de los documentos de Android.


Algunos resúmenes

Hay varios métodos mencionados anteriormente que son buenas prácticas, pero pensé que podría resumirlos con breves explicaciones. A continuación se encuentran algunas de las bibliotecas más populares que se utilizan actualmente para redes http, trabajo asincrónico / subprocesamiento y almacenamiento en caché.

Mi proyecto actual (solo preferencias)

Actualmente estoy usando Otto , Loaders , Volley , Ormlite y una pila de red basada en Apache y Service s. Espero reemplazar, la pila de red en algún momento con Volley , Retrofit , y tal vez eventualmente con Robospice .

Personalmente me gusta mucho Otto and Volley

RoboSpice (Modular)

  • https://github.com/octo-online/robospice
  • http://www.youtube.com/watch?v=ONaD1mB8r-A
  • un complemento / enfoque modular para tareas de larga ejecución
  • esto es como el "cuchillo de ejército suizo" de las bibliotecas, pero necesita saber qué hace cada herramienta.
  • Maneja llamadas REST
  • persiste datos a través de orientación y otros cambios
  • puede manejar el almacenamiento en caché de disco y memoria)
  • funciona con varias bibliotecas HTTP y bibliotecas de persistencia (Gson, Jackson, Spring, OkHttp y muchas de las bibliotecas a continuación)
  • beta para Ormlite con Ormlite , creo

Retrofit (REST)

Volley (datos de red e imágenes)

Picasso (imágenes)

Cargadores (Android)

  • bien soportado
  • persistir a través del cambio de orientación y guardar / cargar el estado del fragmento
  • puede ser difícil de entender
  • sin almacenamiento en caché

AsyncTask (Android)

  • forma simple para el trabajo de fondo desde el hilo de la interfaz de usuario
  • debe ser cancelado y tener cuidado con las tareas que regresan después de que una actividad o fragmento se derriba.

Otto (bus de eventos)

  • https://github.com/square/otto
  • Bus de eventos que facilita el trabajo de sincronización entre componentes y fragmentos
  • La poderosa capacidad de @Produce retiene el último evento y puede producirlo a pedido para cualquier nuevo suscriptor interesado en el bus

Fragmentos sin cabeza (?)

  • Personalmente, nunca he visto este usado más que los tutoriales de Vogella, así que no estoy seguro de este.

Servicio (Android)

  • La vieja escuela
  • control final, debes hacer todo tú mismo
  • generalmente se usa con el cliente Appache o HURL y
  • pasar paquetes alrededor a través de Intents

¿Por qué no prueba los Loaders , en particular AsyncTaskLoader ? Están disponibles para pre-Honeycomb a través de la biblioteca de soporte y combinan a la perfección el ciclo de vida de la actividad / fragmento. Aquí está el resumen oficial:

  • Están disponibles para cada Actividad y Fragmento.
  • Proporcionan carga de datos asincrónica.
  • Monitorean la fuente de sus datos y entregan nuevos resultados cuando el contenido cambia.
  • Se vuelven a conectar automáticamente al cursor del último cargador cuando se vuelven a crear después de un cambio de configuración. Por lo tanto, no necesitan volver a consultar sus datos.

En realidad estamos usando la biblioteca RoboSpice . Se ejecuta en un servicio que solo proporciona objetos RequestListeners.

El problema con su primer acercamiento (Mantener referencias entre el AsyncTask) es que probablemente pueda generar pérdidas de memoria porque cuando sus AsyncTasks contienen sus referencias de Actividades, no serán recolectadas. Esté atento a esto, solo perfile su aplicación revisando el Tamaño del Heap, rotando la misma Actividad una y otra vez. Su montón debe crecer en los parámetros normales (hay un momento en que sus objetos que deben ser basura se acumulan al mismo tiempo con objetos nuevos) pero cuando se ejecuta GC su asignación de RAM debe caer al mismo tamaño que ha asignado en el comenzando.

Entonces, si tengo que recomendar algo, será lo siguiente:

Actividad que gestiona las llamadas y los flujos de la API (con RoboSpice, permitiendo que la UI gire). Pantallas simples dentro de los fragmentos que utilizan retenerInstancia en verdadero. Esto te permite pasar tus DTO directamente a tus fragmentos, y solo debes administrar el estado en la actividad de nivel superior.


Hay muchas maneras en que puedes probar al lado de AsyncTask. Y si intenta encontrar una mejor práctica, AsyncTask no es una buena opción. Esta respuesta explica por qué no debe usar AsyncTask. Y te recomiendan usar una mejor manera que pueda manejar la tarea de ejecución prolongada, https://github.com/octo-online/robospice .
Ya utilicé esta biblioteca y creo que vale la pena intentarlo: respeto a los ciclos de vida de las actividades (cambio de orientación), sin pérdida de memoria, compatible con múltiples subprocesos, resultados de caché ... Puede conectar y desconectar tareas de larga demanda utilizando caché (pero no puede funcionar bien para una solicitud que no sea de caché).

Pero recomiendo que una buena manera venga de Google: IntentService y BroadcastReceiver . Te registrarás y no registrarás durante el cambio de orientación para recibir el resultado de los datos. Todas las tareas en segundo plano funcionarán en IntentService y notificarán a BroadcastReceiver cualquier actividad que desee. Hay muchos ejemplos que puedes probar. Algo como esto: http://mobile.tutsplus.com/tutorials/android/android-fundamentals-intentservice-basics/

Actualización :

Hola R4j, el punto es que mi aplicación es silenciosa y compleja. Y tengo que hacer una serie de llamadas de red paralelas. Su enfoque con IntentService es bueno, pero no es adecuado para escenarios complejos

No creo que esto sea un problema. Puede hacer cualquier cosa con IntentService, incluso las tareas complicadas. Si desea tareas paralelas, puede considerar un Servicio con subprocesamiento múltiple y comunicarse con la actividad por intención. Enviar intenciones entre Servicio y actividad es seguro y flexible, eso es Android.
Y si desea almacenar en caché (mediante descarga de archivos, transmisión en secuencia, por base de datos ...) RoboSpice es la mejor opción para usted


Puedes probar con los siguientes enfoques:

1) Si su aplicación no requiere cambios de orientación de manera explícita , simplemente desactive los cambios de orientación al comienzo de la ejecución de la aplicación, de esta manera evitará bloqueos o problemas relacionados con los cambios de orientación.

Esto lo puede hacer usando la siguiente línea en el diseño más externo de su archivo xml de diseño:

android:orientation="vertical"

(para establecer la orientación vertical)

2) Puede establecer o conservar los valores de orientación anteriores al comienzo de la ejecución de la secuencia utilizando Asynctask, de la siguiente manera ( solo ejemplo de sintaxis ):

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

y

getResources().getConfiguration().orientation


Si el manejo de asyncTask es su principal preocupación, es decir, no desea descargar datos cada vez que se cambia la orientación, puede intentarlo de esta manera:

(1) Inicialice cualquier valor antes en crear así ...

Boolean android_hacker = false;

(2) Ahora cuando haya terminado con la descarga de datos en la clase AsyncTask, establezca ese valor en true

android_hacker = true;

Aquí mantenemos todos los datos utilizando el modelo y la clase de adaptador Array

(3) Ahora, cada vez que se cambia la orientación, marque de esta manera

if( android_hacker = true ){ // Use your saved instance .. }else{ // Download data as it is yet not downloaded .. }

Espero eso ayude ..