Android destruyendo actividades, matando procesos

117

Hola, me pregunto cómo administra Android la memoria y no puedo encontrar una respuesta precisa en ninguna parte. Supongamos que tengo una aplicación con 5 actividades en la pila de actividades actual (4 se detienen y 1 se reanuda), no hay ningún servicio conectado. Presiono el botón INICIO para detener todas mis actividades. Comienzo alguna otra aplicación que consume memoria y la memoria general del dispositivo comienza a ser baja. Y la pregunta es

... ¿Qué pasará con mi aplicación?

  1. ¿El sistema puede destruir solo una o algunas de mis actividades para recuperar la memoria?
  2. ¿El sistema eliminará todo el proceso de mi aplicación? ¿Todas las actividades serán bien destruidas?
  3. ¿Qué pasará cuando vuelva a mi aplicación cuando se eliminó por completo? ¿Comenzará desde el principio (como el primer inicio) o intentará recuperar las actividades al estado anterior? Si es así, ¿es solo el que está en la parte superior de la pila o todos?

ACTUALIZAR:

Antes de hacer esta pregunta, he visto el ciclo de vida de la actividad varias veces, pero no tiene respuestas a mis preguntas. Hice algunas pruebas y tengo algunas respuestas. "Detener proceso" en DDMS fue una pista para la prueba.

No he probado la respuesta para la pregunta 1, pero como dice la guía:

Si una actividad se pone en pausa o se detiene, el sistema puede eliminar la actividad de la memoria pidiéndole que finalice o simplemente matando su proceso.

Parece que una o más de las actividades se pueden destruir suavemente (con el método onDestroy) sin matar el proceso. Simplemente obtendrá (onCreate + bundle) cuando vuelva a ellos.

Respuesta a la pregunta 2:

SI. Generalmente, el sistema mata todo el proceso, esto significa que todos los datos, incluidas las actividades y los campos estáticos, se destruyen. Esto NO se hace bien: no obtendrá onDestroy o finialize () para ninguna de sus actividades pausadas / detenidas. Es por eso que saveInstanceState () se llama justo antes del método onPause. onPause es básicamente el último método en el que debe guardar algo porque después de este método nunca podría ver onStop o onDestroy. El sistema puede simplemente matar el proceso destruyendo todos sus objetos, lo que sea que contengan y lo que sea que estén haciendo.

Respuesta a la pregunta 3:

¿Qué pasará cuando vuelva a una aplicación muerta?

  • Antes de Android 2.2, la aplicación se iniciará desde el principio, con actividad de inicio.
  • A partir de 2.2, el sistema restaurará el estado anterior de la aplicación. Qué significa eso? Significa que se volverá a crear la última actividad visible (onCreate + bundle). ¿Qué pasará con la pila de actividades? La pila está bien, pero todas las actividades están muertas. Cada uno de ellos se volverá a crear (onCreate + bundle) cuando regrese a él con el botón Atrás. Hay una cosa más sobre eso:

Normalmente, el sistema borra una tarea (elimina todas las actividades de la pila por encima de la actividad raíz) en determinadas situaciones cuando el usuario vuelve a seleccionar esa tarea desde la pantalla de inicio. Normalmente, esto se hace si el usuario no ha visitado la tarea durante un período de tiempo determinado, como 30 minutos.

¿Conclusión?

  1. No crea que el manejo de problemas de rotación de actividades puede resolverse con android: configChanges = "Orientación". Cuando hagas eso, tendrás muchos otros problemas de los que ni siquiera eres consciente.
  2. Pruebe su aplicación con DDMS - Botón Detener proceso. Mira esto
  3. Tenga cuidado al utilizar variables estáticas. No piense que cuando los inicializó en la actividad 1, los tendrá inicializados en la actividad 2. El único lugar seguro para inicializar la estática global sería la clase Aplicación.
  4. Recuerde que es posible que nunca vea onStop o onDestroy. Cierre archivos / bases de datos, detenga los descargadores en onPause. Cuando desee que la aplicación haga algo en BG, use el servicio de primer plano.

Eso sería todo ... Espero haber ayudado con mi essey :)

marca
fuente
Para su suposición, ¿esas 5 actividades provienen de una misma aplicación o de varias aplicaciones diferentes?
dumbfingers
1
"Tengo una aplicación con 5 actividades en la pila de actividades actual" Por supuesto, todas son de mi, una misma aplicación de proceso.
Mark
4
Gracias, esta fue exactamente mi pregunta también ... Tu pregunta y las respuestas me ayudaron bastante.
craigrs84
@Mark: ¿Este problema está resuelto ahora? ¿Y si lo es?
Ameer Moaaviah

Respuestas:

30

Primero, eche un vistazo a esto:

img1

onPause () Se llama cuando el sistema está a punto de comenzar a reanudar una actividad anterior. Esto se usa típicamente para confirmar cambios no guardados en datos persistentes, detener animaciones y otras cosas que pueden consumir CPU, etc. Las implementaciones de este método deben ser muy rápidas porque la siguiente actividad no se reanudará hasta que este método regrese. Seguido de onResume () si la actividad vuelve al frente, o onStop () si se vuelve invisible para el usuario.

onStop () Se llama cuando la actividad ya no es visible para el usuario, porque otra actividad se ha reanudado y está cubriendo esta. Esto puede suceder porque se está iniciando una nueva actividad, se está trayendo una existente frente a esta o se está destruyendo esta. Seguido de onRestart () si esta actividad vuelve a interactuar con el usuario, o de onDestroy () si esta actividad va a desaparecer.

Entonces, cuando presiona el botón "INICIO" en su dispositivo, su actividad actual en primer plano se coloca en onPause()ese momento onStop(), los otros 4 deben permaneceronStop()

Según los documentos de Google:

  • Si hay una actividad en el primer plano de la pantalla (en la parte superior de la pila), está activa o en ejecución.
  • Si una actividad ha perdido el foco pero aún es visible (es decir, una nueva actividad transparente o que no es de tamaño completo tiene el foco en la parte superior de su actividad), se detiene. Una actividad pausada está completamente viva (mantiene toda la información de estado y miembros y permanece adjunta al administrador de ventanas), pero el sistema puede eliminarla en situaciones de memoria extremadamente baja.
  • Si una actividad está completamente oculta por otra actividad, se detiene. Todavía conserva toda la información de estado y miembros, sin embargo, ya no es visible para el usuario, por lo que su ventana está oculta y, a menudo, el sistema la eliminará cuando se necesite memoria en otro lugar.
  • Si una actividad se pone en pausa o se detiene, el sistema puede eliminar la actividad de la memoria pidiéndole que finalice o simplemente matando su proceso. Cuando se muestra nuevamente al usuario, debe reiniciarse por completo y restaurarse a su estado anterior.

Y, para el ciclo de vida del proceso:

Ciclo de vida del proceso 3. Una actividad en segundo plano (una actividad que no es visible para el usuario y ha sido pausada) ya no es crítica, por lo que el sistema puede detener su proceso de manera segura para recuperar memoria para otros procesos en primer plano o visibles. Si su proceso necesita ser eliminado, cuando el usuario navega de regreso a la actividad (haciéndola visible en la pantalla de nuevo), se llamará a su método onCreate (Bundle) con el SavedInstanceState que había proporcionado previamente en onSaveInstanceState (Bundle) para que puede reiniciarse en el mismo estado en que el usuario lo dejó por última vez.

Todas las citas anteriores provienen de: Referencia de desarrolladores de Android: Actividad

Se confirma que el sistema puede destruir actividades no activas y reciclar memorias cuando inicias algunas aplicaciones que consumen memoria. Y puede implementar like: isFinishing()en su actividad y luego usar el botón "kill" en DDMS para detectar cuál de sus actividades está siendo descartada por el sistema. Pero supongo que el sistema destruirá primero al más antiguo. Sin embargo, no tiene sentido mantener otras actividades cuando se ha reciclado la "Actividad de lanzamiento".

ACTUALIZAR

Aquí hay algunas opiniones que encontré aquí :

Estado detenido

Cuando una actividad no es visible, pero aún está en la memoria, decimos que está detenida. La actividad detenida podría volver al frente para convertirse nuevamente en una actividad de carrera. O podría destruirse y eliminarse de la memoria.

El sistema mantiene las actividades en un estado detenido porque es probable que el usuario todavía quiera volver a esas actividades pronto, y reiniciar una actividad detenida es mucho más barato que comenzar una actividad desde cero. Esto se debe a que ya tenemos todos los objetos cargados en la memoria y simplemente tenemos que ponerlos todos en primer plano.

Las actividades detenidas se pueden eliminar de la memoria en cualquier momento.

mancuernas
fuente
4
La documentación es bastante confusa sobre este tema, sin embargo, solo se puede matar un proceso completo, no componentes individuales (actividades, servicios, etc.). Ver: stackoverflow.com/questions/7536988/…
greg7gkb
Esta pregunta debe actualizarse con la información en el enlace del comentario de @ greg7gkb, es engañoso
Luke De Feo
1

¿El sistema puede destruir solo una o algunas de mis actividades para recuperar la memoria?

Si. Android elimina las actividades que se ejecutan en segundo plano cuando se necesita memoria. Matar a uno oa todos podría depender de algunas condiciones. Por ejemplo, una instancia pausada o detenida puede hacer que Android elimine una actividad o un proceso en sí. Aquí, en Ciclo de vida de la actividad , puede obtener los siguientes puntos. Te recomiendo que revises esa página por completo. Definitivamente despejará tus dudas.

Si una actividad ha perdido el foco pero aún es visible (es decir, una nueva actividad transparente o que no es de tamaño completo tiene el foco en la parte superior de su actividad), se detiene. Una actividad pausada está completamente viva (mantiene toda la información de estado y miembros y permanece adjunta al administrador de ventanas), pero el sistema puede eliminarla en situaciones de memoria extremadamente baja.

Si una actividad está completamente oculta por otra actividad, se detiene. Todavía conserva toda la información de estado y miembros, sin embargo, ya no es visible para el usuario, por lo que su ventana está oculta y, a menudo, el sistema la eliminará cuando se necesite memoria en otro lugar.

Si una actividad se pone en pausa o se detiene, el sistema puede eliminar la actividad de la memoria pidiéndole que finalice o simplemente matando su proceso. Cuando se muestra nuevamente al usuario, debe reiniciarse por completo y restaurarse a su estado anterior.


¿El sistema eliminará todo el proceso de mi aplicación? ¿Todas las actividades serán bien destruidas?

La actividad pertenece a un individuo, mientras que el proceso pertenece a un grupo de actividades. Mire el tercer punto anterior nuevamente, mata el proceso como se mencionó.


¿Qué pasará cuando vuelva a mi aplicación cuando se eliminó por completo?

Es similar a reiniciar. Nuevamente, el tercer punto le dará algunas respuestas comoWhen it is displayed again to the user, it must be completely restarted and restored to its previous state

Obtenga más información sobre cosas relacionadas con la memoria aquí .

Editar:
todas las actividades de una aplicación se ejecutan en un solo proceso. Entonces, cuando se mata un proceso, todas las actividades, no importa 5 o 10, se eliminarán, es decir, se reiniciarán. El reinicio hará que su aplicación se inicie desde un principio sin estados guardados.

Vinay
fuente
2
He visto el ciclo de vida de la actividad al menos 5 veces, pero no responde a mis preguntas. Lo que dijiste significaría cuando se mata el proceso de mi aplicación: cuando vuelvo a la aplicación, se restaura a su estado anterior. Entonces, cuando tenía 5 actividades detenidas ... ¿murieron todas (se invocaba onDestroy) cuando se mató el proceso? Cuando volví a mi aplicación, ¿se restauraron todas las actividades (onCreate + bundle) o solo la que estaba en la parte superior de la pila (visible para el usuario)?
Mark
1
Todas las actividades de una aplicación se ejecutan en un solo proceso. Entonces, cuando se mata un proceso, todas las actividades, no importa 5 o 10, se eliminarán, es decir, se reiniciarán. El reinicio hará que su aplicación se inicie desde un principio sin estados guardados ..
Vinay
1
Casi cierto, pero no para 2.2 y superior. Vea mi ACTUALIZACIÓN en la parte superior de la página.
Mark
1
No, esto no es cierto y nunca lo ha sido. Es confuso según los documentos, pero consulte: stackoverflow.com/questions/7536988/…
greg7gkb
2
@JJPA Android no puede destruir actividades individuales para recuperar memoria, solo destruye procesos. Vea esta respuesta de Dianne Hackbor, miembro del equipo central de Android involucrado en la implementación del "asesino sin memoria": stackoverflow.com/a/7576275/1290264 .
bcorso