2009-11-07 9 views
8

Esta es una pregunta que he tenido para algunas aplicaciones diferentes que he creado, y aún no me he satisfecho con ninguna de las soluciones que he creado. Pensé que lo pondría allí a la comunidad para ver otras soluciones que podría haber.¿Buenas alternativas para compartir un árbol complejo de objetos entre actividades en Android?

Digamos que tiene una Actividad que descarga un árbol complejo de datos (en este caso vía json, pero podría ser cualquier cosa), deshace los datos a un conjunto de objetos java (en este caso usando gson, pero de nuevo, podría ser lo que sea), luego genera actividades adicionales para ver diferentes partes de esos datos. Puede haber una actividad para ver Trips en su respuesta, y otra para ver Vuelos en esos viajes, y tal vez otra para ver Pasajeros de esos vuelos.

Mi implementación inicial de esta aplicación fue deshacer todos los viajes en la primera actividad, y luego pasarlos por valor (como un extra en la intención) a TripActivity. TripActivity luego pasa vuelos individuales a FlightActivity, y así sucesivamente.

El problema es que hay una pausa notable entre actividades mientras la aplicación serializa y deserializa los datos. Estamos hablando de varios segundos. La pausa es bastante notable cuando mi árbol usa Serialización o Parcelable para pasar datos. Las pruebas iniciales de rendimiento con el uso de Parcelable de Google muestran una aceleración de aproximadamente 30% sobre la serialización, pero Parcelable es difícil de trabajar y no parece manejar referencias circulares de objetos como lo hace la serialización, y además hace pausas durante casi tantos segundos, así que puse ese experimento en el fondo mientras trato otras cosas.

Entonces intenté mover el árbol de objetos directamente a la clase de Aplicación. Cada actividad solo obtiene el árbol directamente de la aplicación cuando lo necesita. Esto hace que el rendimiento sea bastante rápido, pero manejar casos de esquina como inicio/detención de actividad inesperada (debido a bloqueos de actividad o porque la actividad se ha cerrado temporalmente para hacer más memoria disponible, o cualquier otra causa) parece complicado. Tal vez no es más que la implementación de onSaveInstanceState(), no estoy seguro, pero la solución parece un poco hacky, así que no he investigado aún más.

Así que en la búsqueda de una solución menos improvisada, traté de crear un ContentProvider personalizado para almacenar y recuperar mis objetos. Dado que ContentProviders puede configurarse para ejecutarse en proceso usando multiprocess=true, pensé que sería una forma excelente de evitar los costos de serialización mientras hacía algo más "estándar" que almacenar datos en el objeto Aplicación. Sin embargo, ContentProviders no pretendía devolver tipos de objetos arbitrarios, solo admiten tipos como números, cadenas, booleanos, etc. Parece que puedo arreglar uno para almacenar objetos arbitrarios usando ContentResolver.getContentProviderClient().getLocalContentProvider() y accediendo directamente a mi clase personalizada, pero No estoy seguro de que sea menos hacky que almacenar datos en el objeto Aplicación.

Seguramente alguien debe tener una buena solución a este problema. ¿Qué estoy haciendo mal?

Respuesta

3

Además de la solución de fiXedd, otra es usar un servicio local. Haga que el servicio sea "propio" de los objetos, con actividades que llamen a API de servicio para obtener lo que necesite. El servicio también puede ser responsable de buscar y analizar los datos, encapsulando ese bit de lógica.

El objeto Application es el "pelirrojo hijastro" de los componentes de Android.Los miembros del equipo central de Android se han opuesto a la práctica de crear subclases Application personalizadas, aunque ciertamente es compatible con la API. Después de haber diseñado una aplicación ADC2 200 que aprovechó una subclase personalizada Application, puedo decir que también debería haber ido con un servicio en mi caso. En vivo y aprenda ...

Al usar el patrón de encuadernación local, su servicio se creará y destruirá automáticamente según sea necesario, para que no tenga que preocuparse por eso. Y, por definición, un servicio local se ejecuta en el mismo proceso/máquina virtual que sus actividades, por lo que no tiene que preocuparse por ordenar los gastos generales como lo haría en el escenario ContentProvider.

+0

Sí, creo que estoy en un bote similar. Empecé haciendo todo en la aplicación, y ahora parece que un servicio es el camino correcto. Investigaré la refactorización en algún momento. ¡Gracias por el consejo! – emmby

+0

También prefiero el servicio. ¿Qué quieres decir con "propio"? ¿Guarda los datos en un objeto estático en el servicio? Por lo general, un servicio analizará los datos y luego los enviará en una transmisión, y luego se usará un controlador en el hilo de la interfaz de usuario para mostrar los datos o lo que sea. Pero si vuelvo a llamar al servicio, ¿dónde vuelve a obtener el servicio esa información? ¿Se guardan estos datos en un objeto estático en el servicio? No queremos volver a analizar el JSON .. –

1

La forma en que estoy manejando esto en una de mis aplicaciones es descargando los datos y luego metiéndolos en una base de datos. De esta forma no tengo que cargar todos esos objetos (que, IIRC, comer aproximadamente 1kb cada uno solo para la instanciación del objeto) y puedo obtener fácilmente los datos que necesito. No sé si esto funcionará para usted, pero funcionó para mi caso de uso.

+0

Probamos esto en mi trabajo actual, pero la aplicación se congelaba y/o se bloqueaba cuando tratábamos de leer o almacenar datos en la base de datos. Estoy tratando de mantenerme alejado de las bases de datos SQLite de ahora en adelante ... –

0

Otro enfoque sería guardar los objetos de datos en un archivo de preferencias compartidas. Así es como implementamos una de nuestras aplicaciones, pero no me gustó ese enfoque porque parece demasiado lento.

Es una mala práctica de codificación, pero la manera más rápida puede ser simplemente utilizar un servicio para analizar los datos y guardar los datos en una clase estática que puede usar para el resto de la vida de la aplicación.

Cuestiones relacionadas