Android eliminará un proceso si está en segundo plano y el sistema operativo decide que necesita los recursos (RAM, CPU, etc.). Necesito poder simular este comportamiento durante las pruebas para asegurarme de que mi aplicación se esté comportando correctamente. Quiero poder hacer esto de manera automatizada para poder probar si la aplicación se comporta correctamente cada vez que esto sucede, lo que significa que tendré que probar esto en cada actividad, etc.
Sé cómo matar mi proceso. Ese no es el problema. El problema es que cuando mato mi proceso (utilizando DDMS, adb shell kill
, Process.killProcess()
, etc.) Android no se reinicia de la misma manera que lo haría si el sistema operativo Android había matado él mismo.
Si el sistema operativo Android elimina el proceso (debido a los requisitos de recursos), cuando el usuario regrese a la aplicación, Android recreará el proceso y luego recreará la actividad principal en la pila de actividades (llamada onCreate()
).
Por otro lado, si me mato el proceso, Android asume que la actividad en la parte superior de la pila de actividad se comporten mal , por lo que vuelve a crear automáticamente el proceso y luego elimina la actividad de la parte superior de la pila de actividad y recrea la actividad que estaba debajo la actividad principal (llamando a onCreate () `). Este no es el comportamiento que quiero. Quiero el mismo comportamiento que cuando Android mata el proceso.
Solo para explicar gráficamente, si mi pila de actividades se ve así:
ActivityA -> ActivityB -> ActivityC -> ActivityD
Si Android elimina el proceso y el usuario vuelve a la aplicación, Android vuelve a crear el proceso y crea ActivityD.
Si elimino el proceso, Android recrea el proceso y crea ActivityC.
Respuestas:
La mejor manera de probar esto para mí fue hacer esto:
Terminate Application
en la ventana Logcat en Android Studio (esto matará el proceso de la aplicación, asegúrese de seleccionar su dispositivo y procesar en los menús desplegables de Logcat en la parte superior)En algunos dispositivos, también puede volver a la aplicación (ActivityD) con Aplicaciones -> Su icono de inicio, pero en otros dispositivos iniciará la Actividad A.
Esto es lo que dicen los documentos de Android al respecto:
fuente
<activity>
etiqueta en el manifiesto.Esto parece funcionar para mí:
Esto es diferente a lo
adb shell kill
mencionado por el OP.Tenga en cuenta que la ayuda para el
am kill
comando dice:Por lo tanto, no matará el proceso si está en primer plano. Esto parece funcionar como lo quería el OP, ya que si navego fuera de mi aplicación, la ejecuto
adb shell am kill <package_name>
matará la aplicación (lo he confirmado usandops
en el dispositivo). Luego, si vuelvo a la aplicación, vuelvo a la actividad en la que estaba anteriormente, es decir, en el ejemplo del OP, el proceso se recrea y crea ActivityD (en lugar de ActivityC, como la mayoría de los otros métodos de asesinato parecen desencadenarse).Lo siento, llevo un par de años tarde para el OP, pero espero que otros encuentren esto útil.
fuente
adb shell am force-stop
. El último también eliminará cualquier Intento pendiente relacionado con su aplicación (como Notificaciones) mientras que el primero no.am kill
.ps
muestra mi aplicaciónOtro método, probablemente uno que sea programable ya que no requiere DDMS:
Configuración única: vaya a Opciones de desarrollador, seleccione Configuración de límite de proceso en segundo plano, cambie el valor de 'Límite estándar' a 'Sin procesos en segundo plano'.
Cuando necesite reiniciar el proceso, presione el botón de inicio. El proceso se eliminará (puede verificarlo en logcat / Android Monitor en el estudio; el proceso se marcará [MUERTO]). Luego vuelva a la aplicación utilizando el conmutador de tareas.
fuente
Esta pregunta es antigua, pero hay una respuesta para esta pregunta que no requiere adb, Android Studio, etc. El único requisito es API 23 o más reciente.
Para simular el reinicio de la aplicación por sistema operativo, vaya a la configuración de la aplicación mientras su aplicación se está ejecutando, deshabilite (luego puede habilitar) un permiso y devuelva la aplicación desde aplicaciones recientes. Cuando se deshabilita el permiso, el sistema operativo mata la aplicación pero mantiene los estados de instancia guardados. Cuando el usuario devuelve la aplicación, la aplicación y la última actividad (con estado guardado) se recrean.
El método 'Sin procesos en segundo plano' a veces causa el mismo comportamiento, pero no siempre. Por ejemplo, si la aplicación ejecuta un servicio en segundo plano, "No hay procesos en segundo plano" no hace nada. Pero la aplicación puede ser eliminada por el sistema, incluidos sus servicios. El método de permiso funciona incluso si la aplicación tiene un servicio.
Ejemplo:
Nuestra aplicación tiene dos actividades. La actividad A es la actividad principal que se inicia desde el iniciador. La actividad B se inicia desde la actividad A. Solo mostraré los métodos onCreate, onStart, onStop, onDestroy. Android llama a onSaveInstanceState siempre antes de llamar a onStop, porque el sistema puede eliminar una actividad que está en estado de detención. [ https://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle]
Método de permiso:
Quiero comparar otros métodos que se mencionan en las otras respuestas.
No mantener actividades: esto no mata la aplicación.
Método de detención forzada: no almacena estados de instancia guardados
fuente
Service
asesinado muchas veces. Incluso si el sistema no tiene poca memoria. La mayoría de los fabricantes de dispositivos han escrito sus propias "optimizaciones" y "mejoras" para el sistema operativo Android con el fin de ahorrar batería. Muchos dispositivos tienen "asesinos" mucho más agresivos que el Android estándar.Llegué muy tarde a la fiesta y varios antes que yo dieron la misma respuesta correcta, pero para simplificar para quien venga después de mí, simplemente presione el botón de inicio y ejecute este comando:
adb shell ps | grep <package name> | awk '{print $2}' | xargs adb shell run-as <package name again> kill
La aplicación no perderá estado y, según mi propia experiencia, funciona de la misma manera que el sistema operativo eliminó la aplicación en segundo plano. Esto funciona solo para depurar aplicaciones compiladas
fuente
'grep' is not recognized as an internal or external command, operable program or batch file.
run-as <package name> kill 7379
, pero me puso en la actividad anterior, no en la actividad en la que estaba cuando presioné el botón de inicio.Así es como lo haces en Android Studio.
fuente
Android Monitor - Monitors
. Debe ser algo de lo que se hayan librado. Estoy en v 3.2.1Ponga la aplicación en segundo plano con el botón INICIO
Seleccione su proceso en el modo "Logcat" en Android Studio, luego haga clic en Terminar aplicación en la esquina inferior izquierda
Ahora inicie su aplicación desde el iniciador en el dispositivo Android
EDITAR: Según Internet, lo siguiente también funciona:
EDITAR desde el futuro: Algo a tener en cuenta, ha habido un cambio en Android Studio 4.0, si lo usa
Run
desde AS,Terminate
emitirá unForce Stop
.Sin embargo, si inicia desde el iniciador después, y ENTONCES intenta simularlo de esta manera, obtendrá los resultados que desea (comportamiento con poca memoria).
fuente
the behaviour is not the same as what happens when Android kills the process
sí lo esPuede realizar los siguientes pasos para reproducir el comportamiento buscado:
fuente
En las Opciones de desarrollador en Configuración, seleccione 'No mantener actividades', que destruirá las actividades tan pronto como se aleje de ellas.
Nota: Según un comentario útil a continuación, solo use esto si no le importa que se borren los valores estáticos.
fuente
Presiona el botón de Inicio y coloca primero la aplicación en segundo plano. Luego, detenga o elimine el proceso desde DDMS o ADB.
fuente
También puede conectarse a su dispositivo / emulador desde la terminal con
adb shell
, luego obtener el PID de su procesops | grep <your_package_name
y ejecutarlokill -9 <pid>
. Luego abra su aplicación minimizada desde el selector de aplicaciones recientes y reiniciará la última actividadfuente
La raíz de su problema parece ser que
Activity
está en primer plano cuando termina el proceso.Puede observar esto presionando detener en DDMS cuando
Activity
esté visible (sucede exactamente lo que usted describe) y comparándolo con presionar detener después de regresar a casa y luego regresar a la aplicación.Solo asegúrese de
moveTaskToBack(true)
alguna manera en sus pruebas.fuente
No estoy seguro de que esta sea la respuesta que estás buscando, es más como un pensamiento lógico.
No creo que realmente puedas hacer una prueba completamente automatizada, la única forma de simularla será recrearla, también tiene tantas actividades que Android matará tu aplicación.
Entonces, mi idea o sugerencia es crear otra aplicación pequeña, que siga apareciendo nuevas actividades, hasta que Android se quede sin memoria y comience a matar el proceso en segundo plano.
Algo entre la línea:
Inicie la actividad i -> Verifique el proceso de ejecución si la aplicación está en la lista, incremente i y reinicie el ciclo sin cerrar la actividad actual, de lo contrario -> disminuya i y cierre la actividad actual, regrese a la anterior y vuelva a verificar ...
fuente
Cuando el proceso de solicitud finaliza, Android revisa los registros de actividades (las entradas representan actividades en la pila del historial) y decide cuáles mantener en el historial y cuáles eliminar de él.
Uno de los puntos clave aquí es el
ActivityRecord
campo llamadohaveState
, que los ingenieros de Android Framework describen como "¿obtuvimos el último estado de actividad?".Por defecto, Android considera que la actividad tiene un estado. La actividad deja de tener estado cuando la aplicación informa al servicio del administrador de tareas de actividad que la actividad se ha reanudado y esto es válido hasta que la aplicación notifica al marco que la actividad ha entrado en el estado Detenido. En palabras simples, el
haveState
valorfalse
entre la actividadonResume()
se llamaonStop()
oonSaveInstanceState()
se invoca, dependiendo de la versión de destino de la aplicación.En este caso, ActivityD no tiene
android:stateNotNeeded="true"
atributo en el manifiesto de la aplicación y actualmente se está ejecutando en primer plano, por lo que Android lo elimina del historial ya que el sistema no ha alcanzado su último estado.Como se mencionó varias veces, simplemente puede mover la aplicación a un segundo plano, por lo que la actividad principal en la pila de reserva de actividad guardará su estado, y después de eso puede matar el proceso de la aplicación a través de Android Debug Bridge, Android Studio o usando el Propiedad de límite de procesos en segundo plano en las Opciones de desarrollador. Después de eso, su actividad reciente se recreará con éxito.
A pesar de eso, también hay otra forma simple de probar el escenario de muerte del proceso de solicitud. Conociendo todo lo descrito anteriormente y el hecho de que si inicia una nueva ActivityE desde la ActivityD que se está ejecutando actualmente, la
onStop()
devolución de llamada de ActivityD se invoca solo después delonResume()
método ActivityE , puede hacer el siguiente truco.Luego, simplemente comience
TerminatorActivity
cuando desee eliminar la aplicación.Al final hay una herramienta liviana que simplifica la prueba de la muerte de su proceso de aplicación, llamada Venom .
fuente