2012-10-11 40 views
5

En mi aplicación necesito una gran cantidad de productos CRUD: leer registros de la base de datos SQLite local, insertar objetos y actualizar productos. La mayoría de las consultas son tan simples que no se bloquearán aunque se ejecuten en la interfaz de usuario, sin embargo, en esta aplicación quiero adoptar el patrón de Windows Phone: una animación comenzó inmediatamente y se inició en la animación cuando resultado es entregado.Loader framework vs AsyncTask simple

Planeé usar un AsyncTask para el trabajo, sin embargo, noté que Honeycomb (y el paquete compat) presenta esta nueva estructura de cargador . La principal ventaja parece que los datos cargados por un Loader sobreviven a la configuración. El proyecto LoaderEx de Commonsware establece puentes entre SQLite y el marco, pero surgen algunos problemas.

  1. Recursos de limpieza: Yo uso una sola actividad, crear el SQLiteOpenHelper en onCreate() y cerrarla onDestroy(). Dado que el gestor de carga aún puede estar ejecutándose, lo compruebo y configuro un indicador pendingClose en mi objeto de devolución de llamada, por lo que cerrará el cursor y el ayudante cuando termine la carga. Creo que no cerrando la base de datos no es dañina, pero SQLite se queja si no lo haces, y no me gustan los mensajes de error :) El punto aquí es que los datos no sobreviven a los cambios de configuración, por lo que la ventaja del cargador desaparece

  2. ¿Cuántos cargadores debo crear? Digamos que tengo las queridas tablas Customer y Order. Los cargadores se identifican por ID como CUST_L o ORD_L, pero cada vez que el usuario hace clic en algún resumen, quiero mostrar una pantalla con los detalles. ¿Debo I restart un cargador con diferentes parámetros, o debería I init uno nuevo con una identificación aleatoria? Esto puede suceder docenas de veces. ¿El marco del cargador está pensado para muchos trabajos pequeños en ejecución o solo para algunas tareas largas?

  3. ¿Cuál es el propósito de usar ID dentro de la interfaz LoaderCallbacks? ¿Por qué no un simple initLoader(params, callback)? No creo que se pueda reutilizar un poco de lógica dentro de una devolución de llamada: eventualmente se bifurcará (con if-else o switch en ID) por lo que no entiendo el objetivo de dar un identificador al objeto de devolución de llamada, en lugar de un enfoque ingenuo one-callbacks-por-operación.

que estoy pidiendo esto porque todo el marco parece overengineered a mí y sin utilidad real. No entiendo el objetivo de centralizar el código con un LoaderManager, y no puedo ver ninguna nueva oportunidad que AsyncTask no haya ofrecido.

El único punto de victoria es la supervivencia de los cambios de configuración, pero no puedo explotarlo debido a la limpieza de recursos, y no puedo encontrar una manera alternativa de cerrar el SQLiteOpenHelper porque (obviamente) el SQLiteCursorLoader lo requiere pero limpio depende del usuario. Así que AsyncTask parece ser la opción ganadora aquí, pero tal vez me esté perdiendo algo.

+2

"Estoy preguntando esto porque todo el framework me parece superreducido y sin una utilidad real". - No sé acerca de "overengineeredered", pero personalmente, solo uso 'AsyncTask'. Creé 'LoaderEx' para demostrar cómo crear implementaciones alternativas de' Loader', pero poco después de liberarlo, llegué a la conclusión de que 'Loader' era más molesto de lo que valía. La única excepción sería si estuvieras yendo completamente con 'ContentProvider' y pudieras usar' CursorLoader', en cuyo caso soy ambivalente sobre usar eso en vez de 'AsyncTask'. – CommonsWare

+1

Entonces, básicamente, ¿estás de acuerdo con mis suposiciones? ¿Cometí algún error en mi razonamiento? – Raffaele

+0

"¿Entonces básicamente estás de acuerdo con mis suposiciones?" - para el n. ° 1, aunque acepto que es bueno cerrar la base de datos, tenga en cuenta que esto nunca ocurre si utiliza una fachada 'ContentProvider' alrededor de la base de datos, por lo que el marco' Loader' de ContentProvider' no necesariamente hace que esto sea fácil, no es sorprendente. Para el n. ° 2, no puedo estar de acuerdo ni en desacuerdo, ya que me hizo una pregunta en lugar de expresar una opinión, y no tengo una respuesta. Para el n. ° 3, no estoy de acuerdo ni en desacuerdo, ya que no he pensado mucho en su enfoque, ya que no uso 'Loader' por mucho. – CommonsWare

Respuesta

4
  1. Los proveedores de contenido son mucho más poderosos que el enfoque "raw-DB". Muchos enlaces en stackoverflow conducen a discusiones sobre esto.
  2. LoaderManager intenta distinguir los cargadores por sus ID (por eso la firma de initLoader especifica este argumento).Se necesita ID para el cargador para volver a entregar el resultado en caché en caso de que ya existan datos para el cargador con ID específico (por lo tanto, no es necesario volver a cargarlo de forma asíncrona).
  3. llamada restartLoader obliga a LoaderManager a iniciar la operación asincrónica especificada por el cargador creado anteriormente. initLoader intenta reutilizar el cargador existente antes de crear uno nuevo.
  4. Fragmentos y actividades tienen sus propios gestores de carga que no se superponen.

Mi experiencia demuestra que, a pesar de que el uso de proveedores de contenido suena excesivo para implementar, en realidad vale la pena en el futuro. El golpe de rendimiento es insignificante (intenté medirlo), los enlaces de UI-Data se agregan de inmediato (debido a que el observador de contenido y los CursorLoaders pueden suscribirse a las notificaciones de Uri), la sincronicidad implementada por el framework a través de cargadores. En mi humilde opinión, cada vez que se necesita una base de datos, el proveedor de contenido con cargadores la mayoría de las veces es la mejor solución que se te puede ocurrir.

Otros escenarios que implican el uso de la base de datos directamente, le obligarán a implementar todo manualmente.