Tengo una actividad que es la actividad principal utilizada en toda la aplicación y tiene una serie de variables. Tengo otras dos actividades que me gustaría poder utilizar los datos de la primera actividad. Ahora sé que puedo hacer algo como esto:
GlobalState gs = (GlobalState) getApplication();
String s = gs.getTestMe();
Sin embargo, quiero compartir muchas variables y algunas pueden ser bastante grandes, así que no quiero crear copias de ellas como se indicó anteriormente.
¿Hay alguna manera de obtener y cambiar directamente las variables sin usar los métodos get y set? Recuerdo haber leído un artículo en el sitio de desarrollo de Google que decía que no se recomienda para el rendimiento en Android.
Respuestas:
Aquí una compilación de las formas más comunes para lograr esto :
WeakReferences
TL; DR : hay dos formas de compartir datos: pasar datos en los extras del intento o guardarlos en otro lugar. Si los datos son primitivos, cadenas u objetos definidos por el usuario: envíelos como parte de la intención extras (los objetos definidos por el usuario deben implementarse
Parcelable
). Si pasa objetos complejos, guarde una instancia en un singleton en otro lugar y acceda a ellos desde la actividad iniciada.Algunos ejemplos de cómo y por qué implementar cada enfoque:
Enviar datos dentro de intentos
En la segunda actividad:
Use este método si está pasando datos primitivos o cadenas . También puede pasar objetos que implemente
Serializable
.Aunque es tentador, debe pensarlo dos veces antes de usarlo
Serializable
: es propenso a errores y es terriblemente lento. Entonces, en general: manténgase alejado deSerializable
si es posible. Si desea pasar objetos complejos definidos por el usuario, eche un vistazo a laParcelable
interfaz . Es más difícil de implementar, pero tiene considerables ganancias de velocidad en comparaciónSerializable
.Comparta datos sin persistir en el disco
Es posible compartir datos entre actividades guardándolos en la memoria dado que, en la mayoría de los casos, ambas actividades se ejecutan en el mismo proceso.
Nota: a veces, cuando el usuario abandona su actividad (sin abandonarla), Android puede decidir eliminar su aplicación. En tal escenario, he experimentado casos en los que Android intenta iniciar la última actividad utilizando la intención proporcionada antes de que la aplicación fuera eliminada. En estos casos, los datos almacenados en un singleton (ya sea el suyo o
Application
) desaparecerán y podrían ocurrir cosas malas. Para evitar estos casos, puede conservar los objetos en el disco o verificar los datos antes de usarlos para asegurarse de que sean válidos.Usa una clase singleton
Tener una clase para guardar los datos:
De la actividad lanzada:
Usar aplicación singleton
La aplicación singleton es una instancia de la
android.app.Application
cual se crea cuando se inicia la aplicación. Puede proporcionar uno personalizado extendiendoApplication
:Antes de lanzar la actividad:
Luego, desde la actividad lanzada:
Campos estáticos
La idea es básicamente la misma que el singleton, pero en este caso proporciona acceso estático a los datos:
De la actividad lanzada:
HashMapa de
WeakReferences
La misma idea, pero permitiendo que el recolector de basura elimine objetos sin referencia (por ejemplo, cuando el usuario abandona la actividad):
Antes de lanzar la actividad:
De la actividad lanzada:
Puede o no tener que pasar la identificación del objeto usando los extras del intento. Todo depende de tu problema específico.
Persistir objetos en el disco
La idea es guardar los datos en el disco antes de iniciar la otra actividad.
Ventajas: puede iniciar la actividad desde otros lugares y, si los datos ya persisten, debería funcionar bien.
Desventajas es engorroso y lleva más tiempo implementarlo. Requiere más código y, por lo tanto, más posibilidades de introducir errores. También será mucho más lento.
Algunas de las formas de persistir objetos incluyen:
fuente
setResult
método. Además, en ese caso, la actividad secundaria debe invocarse utilizando elstartActivityForResult
métodoActivity
todo y, en suonCreate()
verificación, cualquier campo estático del singleton que complete al iniciar la aplicación. Si ese campo está vacío, regrese a la actividad de inicio usandoFLAG_ACTIVITY_CLEAR_TASK
o aBroadcastReceiver
para eliminar otras actividades.Lo que puedes usar:
Lo que elijas depende de tus necesidades. Probablemente usará más de una forma cuando tenga "mucho"
fuente
MAIN
acción. Después de la muerte del proceso, reinicia en cualquier actividad que se abrió por última vez, que podría ser una página de detalles en algún lugar profundo de la aplicación.¡Haz lo que Google te ordena hacer! aquí: http://developer.android.com/resources/faq/framework.html#3
fuente
Eso no hace una copia (especialmente con String , pero incluso los objetos se pasan por el valor de la referencia, no el objeto en sí, y los getters como ese están bien para usar, posiblemente mejor que otros medios porque son comunes y bien entendido). Los "mitos de rendimiento" más antiguos, como no usar getters y setters, todavía tienen algún valor, pero también se han actualizado en los documentos .
Pero si no quiere hacer eso, también puede hacer que las variables sean públicas o protegidas en GlobalState y acceder a ellas directamente. Y puede hacer un singleton estático como indica el objeto de aplicación JavaDoc :
El uso de datos de intención , como otras respuestas aquí señalan, es otra forma de pasar datos, pero generalmente se usa para datos más pequeños y tipos simples. Puede pasar datos más grandes / más complejos, pero es más complicado que simplemente usar un singleon estático. Sin embargo, el objeto Aplicación sigue siendo mi favorito personal para compartir datos no persistentes más grandes / complejos entre los componentes de la aplicación de Android (porque tiene un ciclo de vida bien definido en una aplicación de Android).
Además, como otros han señalado, si los datos se vuelven muy complejos y necesitan ser persistentes , puede usar SQLite o el sistema de archivos también.
fuente
Puede extender la clase de aplicación y etiquetar cualquier objeto que desee allí, luego estarán disponibles en cualquier lugar de su aplicación
fuente
Hay una nueva y mejor manera de compartir datos entre actividades, y es LiveData . Observe en particular esta cita de la página del desarrollador de Android:
La implicación de esto es enorme: cualquier información del modelo se puede compartir en una clase singleton común dentro de un
LiveData
contenedor. Se puede inyectar de las actividades en sus respectivasViewModel
en aras de la capacidad de prueba. Y ya no necesita preocuparse por las referencias débiles para evitar pérdidas de memoria.fuente
Usar el hashmap del enfoque de referencia débil, descrito anteriormente, y en http://developer.android.com/guide/faq/framework.html me parece problemático. ¿Cómo se reclaman las entradas completas, no solo el valor del mapa? ¿En qué ámbito lo asigna? Como el marco de trabajo controla el ciclo de vida de la Actividad, tener una de las Actividades participantes es responsable de los riesgos de tiempo de ejecución cuando el propietario es destruido antes que sus clientes. Si la aplicación lo posee, alguna actividad debe eliminar explícitamente la entrada para evitar que el hashmap retenga las entradas con una clave válida y una referencia débil recolectada potencialmente basura. Además, ¿qué debe hacer un cliente cuando el valor devuelto para una clave es nulo?
Me parece que un WeakHashMap propiedad de la Aplicación o dentro de un singleton es una mejor opción. Se accede a un valor en el mapa a través de un objeto clave, y cuando no existen referencias fuertes a la clave (es decir, todas las actividades se realizan con la clave y con qué se asigna), GC puede reclamar la entrada del mapa.
fuente
Hay varias formas de compartir datos entre actividades.
1: Pasar datos entre actividades usando Intent
2: Usando la palabra clave estática, defina la variable como estática pública y use cualquier parte del proyecto
usar en cualquier parte del proyecto usando classname.variableName;
3: Uso de la base de datos
pero es un proceso un poco largo, debe usar la consulta para insertar datos e iterar datos usando el cursor cuando sea necesario. Pero no hay posibilidad de perder datos sin limpiar el caché.
4: Uso de preferencias compartidas
mucho más fácil que la base de datos. pero hay alguna limitación: no puede guardar ArrayList, List y los objetos personalizados.
5: Crear getter setter en la clase de Aplicación y acceder a cualquier parte del proyecto.
aquí configurar y obtener de las actividades
fuente
Bueno, tengo algunas ideas, pero no sé si son lo que estás buscando.
Puede utilizar un servicio que contenga todos los datos y luego simplemente vincular sus actividades al servicio para la recuperación de datos.
O empaquete sus datos en un serializable o parcelable y adjúntelos a un paquete y pase el paquete entre actividades.
Puede que este no sea para nada lo que estás buscando, pero también puedes intentar usar Preferencias compartidas o una preferencia en general.
De cualquier manera, hágame saber lo que decide.
fuente
Suponiendo que está llamando a la actividad dos desde la actividad uno usando un Intento.
Puede pasar los datos con intent.putExtra (),
Toma esto como referencia. Envío de matrices con Intent.putExtra
Espero que sea lo que quieras.
fuente
Si su intención es llamar a otras Actividades de la Actividad actual, debe usar Intentos . Su enfoque podría ser menos en los datos persistentes que en compartirlos según sea necesario.
Sin embargo, si realmente necesita conservar estos valores, puede conservarlos en algún tipo de archivo de texto estructurado o base de datos en el almacenamiento local. Un archivo de propiedades, un archivo XML o un archivo JSON podría almacenar sus datos y analizarse fácilmente durante la creación de la actividad. No olvide también que tiene SQLite en todos los dispositivos Android, por lo que podría almacenarlos en una tabla de base de datos. También puede usar un Mapa para almacenar pares clave-valor y serializar el mapa para el almacenamiento local, pero esto puede ser demasiado engorroso para ser útil para estructuras de datos simples.
fuente
Todas las respuestas antes mencionadas son geniales ... Solo estoy agregando una que nadie había mencionado aún sobre la persistencia de datos a través de actividades y que es utilizar la base de datos incorporada de Android SQLite para conservar datos relevantes ... De hecho, puede colocar su databaseHelper en el estado de la aplicación y llámelo según sea necesario a lo largo de las activaciones ... O simplemente haga una clase auxiliar y realice las llamadas a la base de datos cuando sea necesario ... Simplemente agregue otra capa para que considere ... Pero todas las otras respuestas serían suficientes también .. Realmente solo preferencia
fuente
Ejemplo de compartir datos entre actividades pasando un correo electrónico después de iniciar sesión
"correo electrónico" es el nombre que se puede usar para hacer referencia al valor de la actividad que se solicita
1 Código en la página de inicio de sesión
2 código en la página de inicio
fuente
Y si quieres trabajar con un objeto de datos, estos dos implementos son muy importantes:
Serializable vs Parcelable
public class User implements Parcelable
ver más en aquí
fuente