2012-02-21 16 views
5

estoy tratando de pasar datos de una actividad a otra a través de Intent.putExtras así:Intent.putExtras límite de tamaño?

private ArrayList<HashMap<String, String>> mGroups = new ArrayList<HashMap<String, String>>(); 
private ArrayList<HashMap<String, String>> mUsers = new ArrayList<HashMap<String, String>>(); 
... 

Bundle data = new Bundle(); 
data.putInt("mode", mode); 
data.putSerializable("groups", (Serializable) mGroups); 
data.putSerializable("users", (Serializable) mUsers); 
data.putInt("current_class", mCurrentClassId); 
data.putInt("current_user", mCurrentUserId); 

Intent intent = new Intent(ctx, ChildActivity.class); 
intent.putExtras(data); 
ctx.startActivityForResult(intent, 0); 

Aquí mUsers es una lista de HashMap<String,String> con los datos de los usuarios, incluyendo foto con codificación Base64, la suma de los tamaños de cuerdas en este la lista es de aproximadamente 500 Kb

Llamar al startActivityForResult se bloquea durante varios minutos con la pantalla en negro y luego aparece el error ANR. El onCreate de la Sub-Actividad no se llama en absoluto.

Si no agrego grandes cadenas en mUsers (sin fotos codificadas en Base64) - funciona bien.

Por favor ayuda.

+0

Pruebe usar un Parcelable. http://stackoverflow.com/questions/2139134/how-to-send-an-object-from-one-android-activity-to-another-using-intents – DunClickMeBro

+0

¿Ha intentado enhebrar el intento con 'java.lang. Runnable'? –

+1

Tal vez sea mejor si coloca esta 'ArrayList' en un Singleton, podrá acceder a ella desde cada' Activity' en su aplicación. –

Respuesta

7

si ambas actividades son suyas, utilice un modelo de datos decente. Android no recomienda esa aplicación demasiado bien diseñada. O gírelo de forma diferente, permite una aplicación desarrollada rápidamente y no promueve gran parte del buen principio de aplicación de software.

La solución de @Jean-Philippe Roy (¿Québec?) Es interesante, pero singleton son un antipatrón cuando se trata de cosas más elaboradas, como los modelos de estado completo o los servicios.

La mejor opción es utilizar una clase de aplicación. Esta clase es tu singleton, por naturaleza en Android. Así,

  • definen una clase de aplicación en su manifiesto
  • proporcionar un método estático para acceder a la instancia única de la clase de aplicación (siempre es un conjunto unitario).
  • darle un método para recibir y mantener sus datos, llamaremos a partir de su primera actividad
  • y una segunda para que vuelvan en su segunda actividad

--- Actualizado después de la respuesta de @ straya y 18 meses más de programación con Android :)

La cuestión de compartir una estructura de datos o procesos entre aplicaciones, actividades, vistas, fragmentos está siempre presente cuando se crea una aplicación para Android. Es importante conocer y tener en cuenta que el ámbito de aplicación es el lugar adecuado para mantener la estructura compartida, pero utilizando la misma clase de aplicación para poner una estructura de datos en ese ámbito no es viable con respecto a:

  • la calidad del código, si todas las estructuras de datos y procesos compartidos conocen la aplicación, rápidamente se llenará de accesadores para todas esas entidades.
  • sólo hay un conjunto global compartida de entidades, que no se encontró suficiente grano y puede dar lugar a difíciles de detectar formas de entidades de acoplamiento

ahora tienden a preferir el uso de conjuntos unitarios administrados inyección de dependencias. Dagger o RoboGuice permiten crear e inyectar una sola instancia de una clase determinada en otras clases. Esta técnica, y DI más generalmente ofrece grandes posibilidades para buenos diseños de Android:

  • no degradan la calidad del código, incluso se acorta bastante. Use @Inject para inyectar dependencias y se inyectarán.
  • no asigne 2 responsabilidades a la clase singletoned: no manejará la creación de instancia singleton, el framework lo hará.
  • es más fácil pasar de un singleton a una instancia normal
  • como esos singletons se convierten en clases normales con una simple anotación, ya no contienen métodos estáticos y esto permite simularlos fácilmente. Y ese es un gran punto.
  • y, por supuesto, las anotaciones DI dejan en claro cuando una clase depende de otra clase, lo que ayuda a autocodificar el código más.
+0

Gracias, Snicolas, Jean-Phillipe. Lo he implementado temporalmente como un singleton separado, pero definitivamente usaré la clase de aplicación. – Tiger

+1

Esta solución fallará cuando se reinicie su proceso de aplicación y después de que esté restaurando una actividad que intente leer datos desde (más comúnmente, en el método onCreate) –

+0

@SargeBorsch ¡'onSaveInstanceState()' puede guardar en ese caso! –

0

Sólo en respuesta a Snicolas' respuesta:

aplicación ya es un Singleton, no hay necesidad de "volver a" uno.

Personalmente, después de una gran dependencia de la aplicación para mantener los datos durante mucho tiempo, he llegado a no confiar por completo. Sin embargo, utilizo objetos de datos de autocaching para mitigar los problemas;)

+0

Actualizado, gracias. Estoy totalmente de acuerdo con usted ahora mismo. Creo que todavía es bueno considerar que la aplicación es el ámbito adecuado para definir un singleton. Puede no ser tan apropiado usar la clase de aplicación para vincularlos con el alcance de la aplicación. Ahora prefiero 2 patrones, uno de ellos como describes. Actualizaré mi solución para hablar sobre eso. Te invito a que comentes de nuevo si te apetece. – Snicolas

+0

Hola, ¿puedes explicarnos por qué no confiar en la clase de aplicación para almacenar datos? –

+1

@MuhammadBabar porque la aplicación se puede recrear en cualquier momento (teóricamente debido a la poca memoria) por el sistema operativo, y no siempre verá Application.onTerminate() ni llamadas a Application.onLowMemory(). http://stackoverflow.com/questions/12672584/android-app-application-singleton-instance-gets-recreated – straya

Cuestiones relacionadas