Ver la versión completa : [Programación] Problema con el ciclo de vida de una App Android y errores varios!! I need help!!
firesign
20/02/2013, 12:52
Hola.
Esta pregunta va destinada a los que sepan programar para Android en el foro (a ver si la ve Misato :rolleyes:).
La cosa es que tengo una App (la última que he subido a Google Play) que me está dando problemas, que me han llegado sobre todo por "feedback" de usuarios. En esta aplicación voy a tener a los usuarios más "petardos" que os podáis imaginar, y con ello, ya me han ido sacando problemas que ni se me hubieran ocurrido a mi probarlos en toda mi vida.
Bueno, el problema que ahora me tiene "jodido" es el siguiente:
- arranco la aplicación y me muevo por ella
- cuando voy por la tercera o cuarta pantalla, pulso el botón "Home" del móvil, para salir al escritorio
- la aplicación se queda parada y en "background"
- la dejo así durante un tiempo "X", pudiendo hacer uso de otras aplicaciones, o no (simplemente dejar el móvil bloqueado y en el escritorio)
- tras ese tiempo "X", vuelve a arrancar la aplicación
- resulta que la aplicación se inicia SIEMPRE desde la última pantalla en la que estuviera, pero en muchas ocasiones resulta que se han perdido todos los objetos que dicha aplicación tenía en memoria, mostrando errores en esa pantalla, y si se vuelve a pantallas anteriores, también...
El tiempo "X" necesario para que se produzca el error he observado que es totalmente variable según el móvil. Normalmente, si vuelves a la aplicación tras 10 o 15 minutos, no hay ningún problema, todo va bien. Pero si lo haces tras 2 horas, en el S3 de mi mujer se produce el problema, pero en mi Nexus S es necesario esperar más de 1 día para que pase. En cualquier caso, el tiempo es variable, pero si se espera lo suficiente, pasa en todos.
Si se sale de la aplicación mediante el botón "Atrás", no hay ningún problema, como es lógico. La aplicación se cierra totalmente, y al volver a arrancarla empieza desde cero.
Entonces:
:confused: ¿Porque pasa esto? Por más que leo y releo la documentación de Android, cuando una actividad (o aplicación) está parada y es necesario obtener más memoria para el móvil, se destruye. Pero en ningún sitio dicen nada de que pasadas unas horas, se eliminen de la memoria los objetos que tuviera la aplicación en funcionamiento, pero la aplicación se mantenga en el punto en el que estaba... :confused:
Entended que mi objetivo no es guardar el estado de la aplicación para que en el siguiente arranque todo esté como lo dejo. En mi caso, no estoy cerrando la aplicación, y la siguiente vez que se arranque desde cero debería empezar de nuevo totalmente. Lo que no entiendo es que está pasando con las variables, etc, que tengo en memoria de ejecución al quedarse mi aplicación parada, y esperar unas horas. Que en 15 minutos no pase nada, pero en unas horas todo se haya ido al garete y sin embargo la aplicación no se haya matado totalmente... ¿Alguna solución? [Ahhh]
GameMaster
20/02/2013, 12:56
tienes que ver exactamente que haces en esa pantalla, accedes a algun recurso del movil ? dejas algo abierto o pillado ?, y que destruyes al volver hacia atras ? es eso que tienes que mirar, porque al darle al home posiblemente dejes alguna cosa sin finalizar
Monguer Guaper
20/02/2013, 12:57
Tienes que implementar los métodos onStop y onStart de la actividad para guardar el estado de tus variables y que no se pierdan. onStop se llama cuando tu aplicación pasa a segundo plano y onStart cuando el usuario vuelve a abrirla, se haya matado el proceso o no.
Que me corrija misato, porque tengo el android un poco oxidado, pero creo que la pareja de metodos que buscas es esa.
firesign
20/02/2013, 13:05
Pero no tiene demasiado sentido... A ver...
GameMaster:
***********
no se queda nada sin finalizar. De hecho, si le das al botón Home, y después vuelves a la aplicación en pocos minutos, la aplicación sigue funcionando de maravilla. Pasa solo cuando la dejas varias horas.
Monguer:
*******
creo que te refieres al onStop y onRestart, ¿no? Es el onRestart el que se ejecuta al volver desde el estado parado. Lo he probado, he leido todo acerca de esto, pero creo que de verdad no es el caso que se está dando. ¿Tiene sentido que sea necesario el recuperar variables desde el onRestart cuando se ha dejado parado un par de horas, y no cuando se ha dejado parado 15 minutos?
Porque se supone que la única diferencia que puede haber entre esperar 15 minutos o 2 horas es que Android "destruya" completamente tu aplicación, pero nada más, ¿no?
Monguer Guaper
20/02/2013, 13:13
onRestart se llama si tu aplicación no se ha destruido, simplemente se ha quedado en background un rato. En ese caso SI que funciona.
Si la dejas un par de horas y android libera memoria no se llama a onRestart sino a onStart.
http://developer.android.com/images/activity_lifecycle.png
El ciclo de vida de android no te garantiza lo que se destruye o se deja de destruir cuando libera memoria, lo unico que es seguro es que si utilizas los metodos adecuados del ciclo de vida tu aplicacion va a funcionar bien. Si no los usas a veces funcionara y otras no.
-----Actualizado-----
Por lo que entiendo releyendo la imagen, los métodos más apropiados para usar son onPause y onResume.
firesign
20/02/2013, 13:22
Monguer:
********
Si lo miras bien, no hay ninguna posibilidad de que se ejecute onStart sin que se haya ejecutado antes onRestart o onCreate. El problema es que onStart también se ejecuta cuando la aplicación se lanza desde cero, luego ahí mejor no hacer nada, porque lanzando la aplicación desde cero funciona todo perfectamente.
Usar los métodos adecuados del ciclo de vida tampoco tiene mucho sentido. Será más bien usarlos de la forma debida, porque los métodos van a seguir siendo los mismos y se van a ejecutar cuando les toque.
En cualquier caso, yo sigo sin entenderlo, y no he visto en ningún sitio que digan que se puede borrar la memoria de tu aplicación pero no tu aplicación. Además, en mi caso el Bundle que llevan los métodos onCreate, onPause, onResume... no me valen, puesto que utilizo objetos en memoria que no son "serializables"...
Monguer Guaper
20/02/2013, 13:34
Android guarda algunas cosas propias de la aplicacion en el bundle que pasas a oncreate, supongo que por eso te restaura la pila de actividades, pero no los datos propios de tu aplicacion, y por eso te da error.
Guardalas en onPause y restauralas en onResume y dejarás de tener ese error.
firesign
20/02/2013, 13:57
Android guarda algunas cosas propias de la aplicacion en el bundle que pasas a oncreate, supongo que por eso te restaura la pila de actividades, pero no los datos propios de tu aplicacion, y por eso te da error.
Guardalas en onPause y restauralas en onResume y dejarás de tener ese error.
OK. Pero... ¿como las guardo en onPause?
Aparte, se supone que no está ejecutando el onCreate de nuevo cuando vuelvo a la aplicación (o a la actividad) desde el estado "stop". Entonces, no tiene sentido que afecte para nada el Bundle que recibe el onCreate. Y aparte, el Bundle del onCreate tienes que usarlo tú para que sirva de algo, si no, no afecta en absoluto...
^MiSaTo^
20/02/2013, 14:04
Efectivamente como te dice Monguer tienes que implementar onPause y onResume. En el onPause deberías guardar lo que tengas en memoria, cómo? pues depende de los objetos que sean, pero o bien en una BBDD, o bien en un ficherito o bien simplemente serializando el objeto.
Luego básicamente en el onResume lees lo que hayas guardado (de la bbdd, del fichero, el objeto serializado...) y ya "restauras" la pantalla ;). Si es la primera vez que ejecutas la apli o no has guardado la config en el onPause por lo que sea, es tan simple como comprobar si existen esos datos y si no existen no haces nada.
EDIT: De hecho ese mismo problema pasa cuando cambias de orientación el teléfono y la solución es la misma.
Monguer Guaper
20/02/2013, 14:13
OK. Pero... ¿como las guardo en onPause?
Aparte, se supone que no está ejecutando el onCreate de nuevo cuando vuelvo a la aplicación (o a la actividad) desde el estado "stop". Entonces, no tiene sentido que afecte para nada el Bundle que recibe el onCreate. Y aparte, el Bundle del onCreate tienes que usarlo tú para que sirva de algo, si no, no afecta en absoluto...
A ver, cuando va por el camino de la derecha en la imagen que te he puesto, no pasa por oncreate, pero no hace falta porque la aplicacion no se ha destruido. Es por eso que cuando pasa poco tiempo sigue funcionando bien.
Tu problema está cuando va por el camino de la izquierda. La aplicacion guarda el estado del bundle y libera toda la memoria. Cuando el usuario vuelve a la aplicacion, pasa por el oncreate, recupera el bundle (y con el restaura el historial de activities) pero tus variables no están por ninguna parte -> Error.
El bundle del oncreate no tienes que usarlo tu. Cuando sobrescribes el metodo oncreate, lo primero que tienes que hacer es llamar a super.onCreate(bundle) y esa llamada es la que se encarga de restaurar todo el estado generico de la aplicacion.
firesign
20/02/2013, 14:14
Efectivamente como te dice Monguer tienes que implementar onPause y onResume. En el onPause deberías guardar lo que tengas en memoria, cómo? pues depende de los objetos que sean, pero o bien en una BBDD, o bien en un ficherito o bien simplemente serializando el objeto.
Luego básicamente en el onResume lees lo que hayas guardado (de la bbdd, del fichero, el objeto serializado...) y ya "restauras" la pantalla ;). Si es la primera vez que ejecutas la apli o no has guardado la config en el onPause por lo que sea, es tan simple como comprobar si existen esos datos y si no existen no haces nada.
EDIT: De hecho ese mismo problema pasa cuando cambias de orientación el teléfono y la solución es la misma.
¿Y si toda la construcción de la pantalla la tengo implementada en el onCreate y después en otro métodos que se ejecutan en segundo plano (tipicos AsynTask), tengo que cambiar toda la constrccion de la pantalla al onResume?
Monguer Guaper
20/02/2013, 14:20
¿Y si toda la construcción de la pantalla la tengo implementada en el onCreate y después en otro métodos que se ejecutan en segundo plano (tipicos AsynTask), tengo que cambiar toda la constrccion de la pantalla al onResume?
No, porque onCreate se va a llamar siempre que tu aplicación haya "muerto", así que ahí está bien recrear la interfaz.
firesign
20/02/2013, 14:31
No, porque onCreate se va a llamar siempre que tu aplicación haya "muerto", así que ahí está bien recrear la interfaz.
Es que creo que no entiendes exactamente mi situación. El error se produce porque mi aplicación NO HA MUERTO, se ha quedado en estado "Stop", pero no se le ha hecho el "Destroy". Por lo tanto, cuando mi aplicación arranca de forma incorrecta porque ha perdido los datos que tenía, no vuelve a ejecutar el "onCreate", vuelve de estar en "Stop", así que ejecuta solo "onRestart", "onStart" y "onResume"... (mira el gráfico que has puesto antes).
Si mi aplicación pasara por el "Destroy" no tendría ningún problema, pero no se ninguna forma de forzar que al pasarla a background se cierre totalmente... ¿La hay?
-----Actualizado-----
Solución alternativa:
¿se podría comprobar en el onResume si tengo los datos en memoria, y si no los tengo, lanzar directamente la primera Activity de mi aplicación, que lo que hace es el login automático del usuario y volver a obtener todos los datos actualizados? La lanzaría con FLAG_ACTIVITY_CLEAR_TOP para que se olvide de todas las Activities que estuvieran abiertas antes.
Para mi la solución es válida, aunque no se si supondría algún otro problema con el ciclo de vida de Android. Básicamente sería:
@Override
public void onResume() {
super.onResume();
if (customLocation == null) {
Intent intent = new Intent(App.getContext(), SplashScreen.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
}
}
¿Podría ocurrir algo extraño por hacer esto? Básicamente estoy forzando de forma cutre que la aplicación tenga que volver a empezar desde cero (como si estuviera "destruida") aunque no lo estuviera realmente...
Monguer Guaper
20/02/2013, 14:35
Mira el gráfico otra vez. Tu problema es el camino de la izquierda: el sistema libera recursos y tu aplicación se cierra, luego el usuario vuelve a ella, pasa por onCreate y restaura el estado que tenía pero sin tus datos.
Forzar a una aplicación a destruirse cuando la pasas a background es una mala práctica. Un usuario espera poder cambiar entre aplicaciones y que estas mantengan el estado tal cual las dejaron.
Por qué te resulta tan molesto usar onPause y onResume para preservar tus datos?
^MiSaTo^
20/02/2013, 14:45
Haz caso a Monguer que tiene mucha razón en lo que está diciendo ;)
Toda la UI la tienes que crear en onCreate, como es lógico, pero lo que es coger los datos (del location service o de donde sea) deberías tenerlo en el onResume, ya que siempre siempre va a pasar por ahí.
De todos modos te pregunto al igual que el, ¿qué problema hay en implementar onResume/onPause y guardar/restaurar los datos que sean en ellos?
Ah la solución que has pensado con el FLAG_ACTIVITY_CLEAR_TOP es mala práctica por lo que te ha dicho Monguer y añado que no siempre funciona. No deberías romper el ciclo de vida de una aplicación de esa manera, ya está android para gestionar ese tipo de cosas ;)
firesign
20/02/2013, 14:56
Mira el gráfico otra vez. Tu problema es el camino de la izquierda: el sistema libera recursos y tu aplicación se cierra, luego el usuario vuelve a ella, pasa por onCreate y restaura el estado que tenía pero sin tus datos.
Forzar a una aplicación a destruirse cuando la pasas a background es una mala práctica. Un usuario espera poder cambiar entre aplicaciones y que estas mantengan el estado tal cual las dejaron.
Por qué te resulta tan molesto usar onPause y onResume para preservar tus datos?
:lamer: Acabo de ver que no estaba entendiendo el gráfico realmente... :lamer:
Básicamente lo que está pasando entonces es que la Activity se está ejecutando desde cero nuevamente, y como en ella recupero objetos que están guardados a nivel del "singleton" de la App, estos tampoco existen, y de ahí el error...
Ok. Creo que ya lo entiendo, al menos. Otra cosa es que lo logre solucionar :(
Lo de no querer usar el guardado de datos en el onPause y recuperación en onResume básicamente es porque los objetos con los que trabajo en memoria son complejos, no se pueden almacenar en las SharedPreferences, no se pueden serializar, y para guardarlos en tablas de una base de datos internas hay que montar un buen follón...
Si la solución alternativa (con algún cambio, ahora que he creo he entendido que está pasando realmente) no va bien, al final tendré que hacerlo guardando los datos en la base de datos...
-----Actualizado-----
Haz caso a Monguer que tiene mucha razón en lo que está diciendo ;)
Toda la UI la tienes que crear en onCreate, como es lógico, pero lo que es coger los datos (del location service o de donde sea) deberías tenerlo en el onResume, ya que siempre siempre va a pasar por ahí.
De todos modos te pregunto al igual que el, ¿qué problema hay en implementar onResume/onPause y guardar/restaurar los datos que sean en ellos?
Ah la solución que has pensado con el FLAG_ACTIVITY_CLEAR_TOP es mala práctica por lo que te ha dicho Monguer y añado que no siempre funciona. No deberías romper el ciclo de vida de una aplicación de esa manera, ya está android para gestionar ese tipo de cosas ;)
Como le comento a Monguer, lo de no querer usar el guardado de datos en el onPause y recuperación en onResume básicamente es porque los objetos con los que trabajo en memoria son complejos, no se pueden almacenar en las SharedPreferences, no se pueden serializar, y para guardarlos en tablas de una base de datos internas hay que montar un buen follón...
Pero me temo que al final lo voy a tener que usar.
Pero hay una cosa que sigue sin quedarme clara de lo que me dices: si la UI se crea en el onCreate, y coger los datos y demás lo tengo en el onResume, y yo en la UI necesito usar esos datos... ¿No tendría sentido hacerlo así, no? Porque según el gráfico, el onCreate se ejecuta antes que el onResume (que es lógico).
Monguer Guaper
20/02/2013, 14:58
:lamer: Acabo de ver que no estaba entendiendo el gráfico realmente... :lamer:
Básicamente lo que está pasando entonces es que la Activity se está ejecutando desde cero nuevamente, y como en ella recupero objetos que están guardados a nivel del "singleton" de la App, estos tampoco existen, y de ahí el error...
Ok. Creo que ya lo entiendo, al menos. Otra cosa es que lo logre solucionar :(
Lo de no querer usar el guardado de datos en el onPause y recuperación en onResume básicamente es porque los objetos con los que trabajo en memoria son complejos, no se pueden almacenar en las SharedPreferences, no se pueden serializar, y para guardarlos en tablas de una base de datos internas hay que montar un buen follón...
Si la solución alternativa (con algún cambio, ahora que he creo he entendido que está pasando realmente) no va bien, al final tendré que hacerlo guardando los datos en la base de datos...
No se pueden serializar? Puedes poner un ejemplo básico para echar un vistazo? En teoría se tendría que poder a no ser que tengan atributos no serializables y de los cuales no tengas el código...
^MiSaTo^
20/02/2013, 15:04
Como le comento a Monguer, lo de no querer usar el guardado de datos en el onPause y recuperación en onResume básicamente es porque los objetos con los que trabajo en memoria son complejos, no se pueden almacenar en las SharedPreferences, no se pueden serializar, y para guardarlos en tablas de una base de datos internas hay que montar un buen follón...
Pero me temo que al final lo voy a tener que usar.
Pero hay una cosa que sigue sin quedarme clara de lo que me dices: si la UI se crea en el onCreate, y coger los datos y demás lo tengo en el onResume, y yo en la UI necesito usar esos datos... ¿No tendría sentido hacerlo así, no? Porque según el gráfico, el onCreate se ejecuta antes que el onResume (que es lógico).
No se qué objetos estás usando pero practicamente cualquiera se puede serializar. No deberías tener que guardarlos en una BBDD y mucho menos en las SharedPreferences que eso es para config de la apli y no para este tipo de casos.
Si nos pones un ejemplo quizá te ayudemos más.
Sobre lo del onCreate y onResume, la idea es que los layout los inicialices en onCreate, y ahí inicialices cualquier cosa de la UI peeeero por ejemplo el texto de un textField se lo puedes poner en el onResume sin ningún problema ya que el elemento estará creado.
De todos modos, tampoco se qué quieres hacer exactamente y así a ciegas es dificil ayudarte :(
IronArthur
20/02/2013, 15:25
Creo que esto junto con el girar la pantalla es el problema-atasco tipico una vez llegado a desarrollo "intermedio-avanzado" en Android, pq no es algo que se explique en la mayoría de los cursos o libros básicos de Android.
Salu2
^MiSaTo^
20/02/2013, 15:31
Creo que esto junto con el girar la pantalla es el problema-atasco tipico una vez llegado a desarrollo "intermedio-avanzado" en Android, pq no es algo que se explique en la mayoría de los cursos o libros básicos de Android.
Salu2
Efectivamente, por eso he hecho edit en mi otro mensaje añadiendo lo de la rotación xD
IronArthur
21/02/2013, 09:12
es una de las cosas que más odio de Android el tema de tener que salvar el viewstate y no saber si tu aplicacion ha muerto o q.
Salu2
^MiSaTo^
21/02/2013, 09:29
es una de las cosas que más odio de Android el tema de tener que salvar el viewstate y no saber si tu aplicacion ha muerto o q.
Salu2
Y que el ciclo de vida de las activities no siempre se cumple. Normalmente sí, pero hay casos que no xD
IronArthur
21/02/2013, 09:43
Me acabas de recordar una conversación que tuve con un ex-compañero de la uni que tiene un empresa que hacen cosas con android:
E: que tal desarrollando con Android?
Y: pfssssss, si pero tiene sus cosillas que..... pffff
E: Ves! se nota que has desarrollado con Android. Hago entrevistas con gente que le preguntas que tal android, y todos te dicen "super bien, es fácil, una maravilla" y una mierda!
:D
Salu2
^MiSaTo^
21/02/2013, 09:44
Exacto xDD Comparto lo que dice ;)
firesign
21/02/2013, 09:58
Por aqui sigo...
El tema de serializar los objetos, en cualquier caso, ¿como guardaríais los objetos ya serializados? Porque para mandarlos en un Bundle vale, pero por más que he buscado como guardarlos en onPause y recuperarlos en onResume, todo lo que encuentro es usando las SharedPreferences (que como dice Misato no es para esto, pero da el apaño en cualquier caso), o en una Base de Datos...
Y en la Base de Datos o en las SharedPreferences, no vale para nada serializarlos. Por lo tanto, ¿que opción sería la recomendable para guardarlos?
Yo el tema de rotar la pantalla tampoco me ha preocupado mucho hasta ahora porque en todas las Apps que he hecho no permito la rotación. Todas tienen su interfaz preparado para usarse en vertical, o en horizontal, pero no he hecho ninguna hasta ahora que se adapte a ambas.
Monguer Guaper
21/02/2013, 10:11
Una vez serializado haz un write a un file mismamente.
Has conseguido serializarlo al final?
en el evento
onSaveInstanceState
Te da un objeto en el que puedes guardar tus datos y recuperarlos en oncreate
http://developer.android.com/training/basics/activity-lifecycle/recreating.html#SaveState
Saludos
^MiSaTo^
21/02/2013, 10:21
Bueno, para serializar objetos lo mejor no es que uses Serializable sino Parcelable, que en Android funciona mejor (y vale para lo mismo).
Después puedes guardar en un fichero esos objetos tranquilamente. En la documentación hablan de guardar las cosas en un SQLite o en SharedPreferences, pero tb hablan de que las preferencias deben ser eso, preferencias del usuario.
Yo personalmente creo que depende del tipo de objeto que tengas (que aún no nos has dicho cómo es) deberías o usar eso o un fichero y punto. (Es más yo soy muy amiga de lo del fichero)
-----Actualizado-----
en el evento
onSaveInstanceState
Te da un objeto en el que puedes guardar tus datos y recuperarlos en oncreate
http://developer.android.com/training/basics/activity-lifecycle/recreating.html#SaveState
Saludos
El problema es que eso para el onPause/onResume no vale ;)
Sólo para cuando se destruye la aplicación.
firesign
21/02/2013, 10:37
OK. Pues seguiré dándole vueltas a ver si se me ocurre algo que parchee lo que tengo hecho y me ahorre tener que cambiar la App de arriba a abajo (puesto que no he hecho correctamente la creación de la interfaz de las Activities, y ahora tener que cambiar todo a esta forma sería terrible).
Si no se me ocurre como, intentaré el método de guardarlo todo a un fichero, aunque me va a llevar semanas cambiarlo todo para que funcione correctamente :(
No he comentado nada del objeto, porque son varios, cada uno de su padre y de su madre. Pero vamos, básicamente guardan diferentes datos dentro, como cadenas, enteros, doubles o booleans, vectores, locations, y alguna que otra imagen (bitmap). Por ejemplo, hay un objeto "user" cuya instancia guarda datos como el nombre, edad, email, twitter, varios booleans de su configuración, un vector con los últimos votos (que a su vez es otro objeto "vote") que ha hecho, un bitmap con su imagen de usuario, un location con su última posición registrada, etc...
-----Actualizado-----
Y por cierto, que ya que estamos, la App para la cual viene toda esta historia es esta:
www.jaleoo.com
https://play.google.com/store/apps/details?id=com.jaleoo.firesign
(a Misato ya le comenté vía Google Talk hace un tiempo que estábamos liados con este tema, aunque no le comenté nombre de la App ni nada).
En ella se puede observar que se produce el error que comentaba en mis primeros post del hilo. En cualquier caso, por ahora no os vale de mucho si no sois de Cádiz, je je. Y Misato seguramente no la podrá descargar porque solo está activada en Google Play para España. Vamos poco a poco, y no comenzaremos a intentar abarcar el resto de provincias de España hasta que no tengamos lista la versión de iOS, que ahora mismo está en el horno y esperamos tenerla en cosa de 1 mes.
Monguer Guaper
21/02/2013, 10:38
en el evento
onSaveInstanceState
Te da un objeto en el que puedes guardar tus datos y recuperarlos en oncreate
http://developer.android.com/training/basics/activity-lifecycle/recreating.html#SaveState
Saludos
Además ahí no es recomendable guardar datos de negocio de la aplicación, sino cosas como el estado de la interfaz.
Y estoy con misato en lo del Parcelable, que a mi se me había olvidado pero si que es mucho mas recomendable por eficiencia, aunque cueste un pelín más de esfuerzo implementarlo.
El problema es que eso para el onPause/onResume no vale ;)
Sólo para cuando se destruye la aplicación.
Pero es que en esos casos no se destruyen los objetos en memoria, asi que no hace falta almacenarlos.
Monguer, a no ser que me pierda algo es el mismo caso que un giro de pantalla, y para eso esta el onSaveInstance.
^MiSaTo^
21/02/2013, 11:25
Pero es que en esos casos no se destruyen los objetos en memoria, asi que no hace falta almacenarlos.
Monguer, a no ser que me pierda algo es el mismo caso que un giro de pantalla, y para eso esta el onSaveInstance.
Si puede que se destruyan si la apli está en segundo plano y el so se queda sin memoria ;)
Si puede que se destruyan si la apli está en segundo plano y el so se queda sin memoria ;)
Momento en el que se llama a onSaveInstance
firesign
21/02/2013, 11:39
Momento en el que se llama a onSaveInstance
Si esto es cierto, valdría para mi caso. Es decir, si siempre que la aplicación está "parada" pero no "destruida" y el SO se queda sin memoria, borrando la de la App, se llama a onSaveInstance, me vendría de perlas.
^MiSaTo^
21/02/2013, 11:50
Momento en el que se llama a onSaveInstance
No siempre ;)
Si miras la documentación aquí (http://developer.android.com/reference/android/app/Activity.html#onSaveInstanceState%28android.os.Bun dle%29) y aquí (http://developer.android.com/guide/components/activities.html) dicen claro que no hay garantía de que no se llame después del onStop en vez de el onPause:
Note: There's no guarantee that onSaveInstanceState() will be called before your activity is destroyed, because there are cases in which it won't be necessary to save the state (such as when the user leaves your activity using the Back button, because the user is explicitly closing the activity). If the system calls onSaveInstanceState(), it does so before onStop() and possibly before onPause().
Si tu app está en segundo plano, a veces pasa que libera memoria pero no destruye la app. En cuyo caso, no llama al onSaveInstanceState. Por eso desde la doc oficial tb recomiendan salvar lo que sea en el onPause en según qué casos.
Monguer Guaper
21/02/2013, 11:52
Yo creo que otto está en lo cierto, precisamente se llama a onsaveinstance cuando es el sistema el que destruye la aplicacion, ya sea por rotar o por liberar recursos.
Pero sigo insistiendo en que creo que el bundle no es el sitio adecuado para guardar grandes cantidades de datos, como mucho el estado de la interfaz de la actividad y poco mas.
Por poderse, se puede guardar ahí, pero creo que no es su sitio.
^MiSaTo^
21/02/2013, 12:02
Yo creo que otto está en lo cierto, precisamente se llama a onsaveinstance cuando es el sistema el que destruye la aplicacion, ya sea por rotar o por liberar recursos.
Pero sigo insistiendo en que creo que el bundle no es el sitio adecuado para guardar grandes cantidades de datos, como mucho el estado de la interfaz de la actividad y poco mas.
Por poderse, se puede guardar ahí, pero creo que no es su sitio.
Ya pero el caso es que la app va a segundo plano y al tiempo se destruye.
Si lo haces en el onSaveInstanceState, nada te garantiza que cuando vuelvas de segundo plano eso funcione bien. Y aparte, si el SO necesita memoria, puede no destruir la app pero si liberar memoria de la misma.
Habría que ver con detenimiento cómo es la app y dónde conviene más hacerlo porque además esque vamos a ciegas si no sabemos cómo es la app ;)
Monguer Guaper
21/02/2013, 12:18
Ya pero el caso es que la app va a segundo plano y al tiempo se destruye.
Si lo haces en el onSaveInstanceState, nada te garantiza que cuando vuelvas de segundo plano eso funcione bien. Y aparte, si el SO necesita memoria, puede no destruir la app pero si liberar memoria de la misma.
Habría que ver con detenimiento cómo es la app y dónde conviene más hacerlo porque además esque vamos a ciegas si no sabemos cómo es la app ;)
Leo en la documentacion:
There's no guarantee that onSaveInstanceState() will be called before your activity is destroyed, because there are cases in which it won't be necessary to save the state (such as when the user leaves your activity using the Back button, because the user is explicitly closing the activity). If the system calls onSaveInstanceState(), it does so before onStop() and possibly before onPause().
Lo que entiendo de ahí es que si el usuario cierra explicitamente la aplicación, no hace falta llamar a onsaveinstancestate porque al volver no espera encontrar el estado restaurado, pero cuando se llama se hace antes de onstop, y onStop se llama antes de que tu aplicación se vaya a segundo plano, luego si el sistema la cierra, creo que siempre pasará por ahí. Si se me escapa algo dímelo, pero creo que es como he entendido.
Y lo de liberar la memoria de la aplicacion sin destruirla nunca lo había oido, y si es así me parece un diseño terrorifico y me extraá muchisimo que no esté documentado, porque si tienes lógica en el ondestroy y te encuentras que tus datos se pierden antes de que llegue esa llamada... Vamos, que me extraña muchisimo.
Yo creo que otto está en lo cierto, precisamente se llama a onsaveinstance cuando es el sistema el que destruye la aplicacion, ya sea por rotar o por liberar recursos.
Pero sigo insistiendo en que creo que el bundle no es el sitio adecuado para guardar grandes cantidades de datos, como mucho el estado de la interfaz de la actividad y poco mas.
Por poderse, se puede guardar ahí, pero creo que no es su sitio.
Ahi estoy de acuerdo.
Pero como lo normal es querer recuperar el estado de la vista, se saca de ahi, y luego en onresume recuperas el estado mas actual de tus datos, sea la fuente que sea, db, desde fuera, un objeto serializado.
Tengo que mirarme lo de parcelable, no lo he usado nunca.
-----Actualizado-----
En resumen, que me explico como un ojete.
Creo que usando los mecanismos tipo de android como los distintos eventos + adquisicion de datos se puede simplificar el problema y resolverlo.
Saludos
firesign
21/02/2013, 13:55
Y lo de liberar la memoria de la aplicacion sin destruirla nunca lo había oido, y si es así me parece un diseño terrorifico y me extraá muchisimo que no esté documentado, porque si tienes lógica en el ondestroy y te encuentras que tus datos se pierden antes de que llegue esa llamada... Vamos, que me extraña muchisimo.
Pues esto es precisamente lo que está pasando en mi caso. Android se está fundiendo todo lo que la App tiene en memoria, pero al volver a ella, se está arrancando desde la Activity que estaba en funcionamiento al dejarla parada, en lugar de volver a empezar por la Activity inicial. Si Android estuviera destruyendo la aplicación, no tendría este problema, porque a mi lo que me conviene es que siempre al usuario darle al icono de la App se empiece desde el principio, ya que la App está terminada pero no está "bien construida según toda esta historia".
Tampoco se mucho más que deciros sobre la App, más que la podéis ver y probar en donde os puse antes:
https://play.google.com/store/apps/details?id=com.jaleoo.firesign
Es bastante compleja, y no sabría bien que comentaros aquí sobre ella...
Monguer Guaper
21/02/2013, 14:01
Pues esto es precisamente lo que está pasando en mi caso. Android se está fundiendo todo lo que la App tiene en memoria, pero al volver a ella, se está arrancando desde la Activity que estaba en funcionamiento al dejarla parada, en lugar de volver a empezar por la Activity inicial. Si Android estuviera destruyendo la aplicación, no tendría este problema, porque a mi lo que me conviene es que siempre al usuario darle al icono de la App se empiece desde el principio, ya que la App está terminada pero no está "bien construida según toda esta historia".
Tampoco se mucho más que deciros sobre la App, más que la podéis ver y probar en donde os puse antes:
https://play.google.com/store/apps/details?id=com.jaleoo.firesign
Es bastante compleja, y no sabría bien que comentaros aquí sobre ella...
Nooooooooooooo, pensaba que esto había quedado claro! Jaja!
En tu caso android destruye TODA la aplicación, memoria y actividades, lo que pasa es que automaticamente guarda ciertas cosas en el bundle (como por ejemplo la ultima actividad en la que te encontrabas) y luego las restaura al volver a crearse.
Por eso te piensas que no la destruye, pero SI la destruye y la restaura despues (todo excepto tus datos, porque al ser propios tuyos no sabe como hacerlo y por eso tienes que encargarte tu :D )
ale_fran
16/03/2013, 20:21
Hola!
He leido el debate y es algo de lo que estoy teniendo problemas..
Se puede utilizar el onPause y el onRestart para cuando se saca una foto?
El problema mio es que tengo varias actividades y una de ella cuando hago click en un boton va a la camara, saca la foto y vuelve y la asigna a un imageView. El problema es que a veces me pasa que se queda sin memoria o algo asi, y va hacia la primera actividad pasando por el onCreate, y cargando e inicializando todo de nuevo con los asyntask q tengo...
Una especie de codigo asi tengo:
btnActionPhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
int code = TAKE_PICTURE;
Uri output = Uri.fromFile(new File(name));
intent.putExtra(MediaStore.EXTRA_OUTPUT, output);
startActivityForResult(intent, code);
}
});
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == TAKE_PICTURE) {
if (data != null) {
if (data.hasExtra("data")) {
iv = (ImageView)findViewById(R.id.img1);
iv.setImageBitmap((Bitmap) data.getParcelableExtra("data")); }
}
else
{
// A partir del nombre del archivo creamos el bitmap para el ImageView
iv = (ImageView)findViewById(R.id.img1);
iv.setImageBitmap(BitmapFactory.decodeFile(name));
}
}
if ( resultCode == 0 ) //Se hace cancelar al momento de sacar la foto.
}
Como puedo hacer para que en el onPause quede grabado??
Muchas gracias!!!
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.