studio programacion herramientas fundamentos con avanzado aplicaciones android

programacion - Cómo simular que Android está matando mi proceso



manual de android en pdf (14)

Android matará un proceso si está en segundo plano y el SO decide que necesita los recursos (RAM, CPU, etc.). Necesito ser capaz de simular este comportamiento durante la prueba para asegurarme de que mi aplicación se comporte correctamente. Quiero poder hacer esto de manera automatizada para que pueda 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 elimino mi proceso (usando DDMS, adb shell kill , Process.killProcess() , etc.), Android no lo reinicia de la misma forma que lo haría si el sistema operativo Android lo hubiera matado.

Si el sistema operativo Android mata el proceso (debido a los requisitos de recursos), cuando el usuario regrese a la aplicación, Android recreará el proceso y luego volverá a crear la actividad principal en la pila de actividades (invocando onCreate() ).

Por otro lado, si elimino el proceso, Android asume que la actividad en la parte superior de la pila de actividades se comportó mal , por lo que recrea el proceso automáticamente y luego elimina la actividad superior de la pila de actividades y recrea la actividad que estaba debajo la actividad principal (invocar onCreate () `). Este no es el comportamiento que quiero. Quiero el mismo comportamiento que cuando Android mata el proceso.

Solo para explicarlo de forma gráfica, si mi pila de actividades tiene este aspecto:

ActivityA -> ActivityB -> ActivityC -> ActivityD

Si Android mata el proceso y el usuario vuelve a la aplicación, Android recrea el proceso y crea ActivityD.

Si elimino el proceso, Android recrea el proceso y crea ActivityC.


Así es como lo haces en Android Studio.

  1. Haga que su dispositivo en modo de depuración esté conectado a su computadora.
  2. Abra la aplicación en su dispositivo y vaya a la actividad que desee probar "Volver a ella desde la muerte".
  3. Presione el botón Inicio en su dispositivo.
  4. En Android Studio ve a Monitor de Android -> Monitores y presiona el ícono de Terminar aplicación.
  5. Ahora puede volver a su aplicación a través de las aplicaciones recientes o al hacer clic en su icono de inicio, el comportamiento ha sido el mismo en mis pruebas.

En las opciones de Desarrollador en Configuración, selecciona "No guardar actividades", lo que destruirá las actividades tan pronto como te alejes de ellas.


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 posterior.

Para simular el reinicio de la aplicación por SO, vaya a la configuración de la aplicación mientras se ejecuta, desactive (luego puede habilitar) un permiso y devuelva la aplicación desde aplicaciones recientes. Cuando el permiso está desactivado, el sistema operativo mata a la aplicación, pero mantiene los estados guardados de la instancia. Cuando el usuario devuelve la aplicación, la aplicación y la última actividad (con estado guardado) se vuelven a crear.

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, "Sin 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. ActivityA es la actividad principal que se inicia desde el iniciador. ActivityB se inicia desde ActivityA. Mostraré solo en los métodos Crear, poner en marcha, detener, en Destruir. Android llama a SaveInstanceState siempre antes de llamar a OnStop, ya que 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:

<start app from launcher first time> Application onCreate ActivityA onCreate WITHOUT savedInstance ActivityA onStart <open ActivityB> ActivityB onCreate WITHOUT savedInstance ActivityB onStart ActivityA onStop (the order is like this, it is stopped after new one is started) <go settings> ActivityB onStop <disable a permission> //Application is killed, but onDestroy methods are not called. //Android does not call onDestroy methods if app will be killed. <return app by recent apps> Application onCreate (this is the important part. All static variables are reset.) ActivityB onCreate WITH savedInstance (user does not notice activity is recreated) //Note that ActivityA is not created yet, do not try to access it. ActivityB onStart <return ActivityA by back> ActivityA onCreate WITH savedInstance (user does not notice activity is recreated) ActivityA onStart ActivityB onStop ActivityB onDestroy <press back again, return launcher> ActivityA onStop ActivityA onDestroy <open app again> //does not call Application onCreate, app was not killed ActivityA onCreate WITHOUT savedInstance ActivityA onStart

Quiero comparar otros métodos que se mencionan en las otras respuestas.

No mantener actividades: esto no mata la aplicación.

<start app from launcher first time> Application onCreate ActivityA onCreate WITHOUT savedInstance ActivityA onStart <open ActivityB> ActivityB onCreate WITHOUT savedInstance ActivityB onStart ActivityA onStop ActivityA onDestroy (do not keep) <return launcher by home button> ActivityB onStop ActivityB onDestroy (do not keep) <retun app from recent apps> // NO Application onCreate ActivityB onCreate WITH savedInstance (user does not notice activity recreated) ActivityB onStart <return ActivityA by back> ActivityA onCreate WITH savedInstance (user does not notice activity recreated) ActivityA onStart ActivityB onStop ActivityB onDestroy <press back again, return launcher> ActivityA onStop ActivityA onDestroy <open app again> //does not call Application onCreate, app was not killed ActivityA onCreate WITHOUT savedInstance ActivityA onStart

Forzar método de detención: no almacena estados de instancia guardados

<start app from launcher first time> Application onCreate ActivityA onCreate WITHOUT savedInstance ActivityA onStart <open ActivityB> ActivityB onCreate WITHOUT savedInstance ActivityB onStart ActivityA onStop <go settings> ActivityB onStop <force stop, return app from recent apps> Application onCreate ActivityA onCreate WITHOUT savedInstance //This is important part, app is destroyed by user. //Root activity of the task is started, not the top activity. //Also there is no savedInstance.


Esto parece funcionar para mí:

adb shell am kill <package_name>

Esto es diferente a adb shell kill mencionado por el OP.

Tenga en cuenta que la ayuda para el comando am kill dice:

am kill: Kill all processes associated with <PACKAGE>. Only kills. processes that are safe to kill -- that is, will not impact the user experience.

Por lo tanto, no matará el proceso si está en primer plano. Esto parece funcionar ya que el OP quería que si me alejaba de mi aplicación, ejecutara adb shell am kill <package_name> que matara la aplicación (lo he confirmado usando ps en el dispositivo). Luego, si regreso 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 matar parecen desencadenar).

Lamento que llegue un par de años más tarde al OP, pero espero que a otros les resulte útil.


La mejor manera de probar esto para mí fue haciendo esto:

  • Abra ActivityD en su aplicación
  • Presione el botón de inicio
  • Presione Detener en DDMS en su aplicación (esto matará el proceso de la aplicación)
  • Regrese a la aplicación con la aplicación de inicio prolongado o aplicaciones abiertas (depende del dispositivo)
  • La aplicación comenzará en ActivityD recreado (ActivityA, ActivityB, ActivityC están muertos y se volverán a crear cuando vuelvas a ellos)

En algunos dispositivos también puede volver a la aplicación (ActivityD) con Aplicaciones -> Su icono de iniciador, pero en otros dispositivos iniciará ActivityA en su lugar.

Esto es lo que dicen los documentos de Android sobre eso:

Normalmente, el sistema borra una tarea (elimina todas las actividades de la pila por encima de la actividad raíz) en ciertas 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.


La raíz de tu problema parece ser que tu Activity está en primer plano cuando matas el proceso.

Puede observar esto al presionar detener en DDMS cuando la Activity es visible (sucede exactamente lo que usted describe) y comparar eso con presionar detener después de la casa y luego volver a la aplicación.

Solo asegúrate de moveTaskToBack(true) alguna manera en tus pruebas.


Llego muy tarde a la fiesta y varios antes que yo dieron la misma respuesta correcta, pero para simplificar para quien venga detrá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 del mismo modo que el sistema operativo eliminó la aplicación en segundo plano. Esto funciona solo para aplicaciones compiladas de depuración


No estoy seguro de que esta es la respuesta que está buscando, es más como una lógica pensar.

No creo que puedas hacer una prueba totalmente automática, la única forma de simularlo será recreando, AKA tiene tantas actividades que Android matará tu aplicación.

Así que mi idea o sugerencia es hacer 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:

Iniciar actividad i -> Verifique el proceso de ejecución si la aplicación está en la lista, incremente iy reinicie el ciclo sin cerrar la actividad actual, de lo contrario -> disminuya iy cierre la actividad actual, regrese a anterior y vuelva a verificar ...


Otro método, probablemente uno que sea programable porque no requiere DDMS:

Configuración de una sola vez: 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 verificar en Logcat / Android Monitor en el estudio - el proceso se marcará como [DEAD]). Luego vuelva a la aplicación usando el selector de tareas.


Para todos, solo quería que supieras acerca de este documento que encontré:

http://developer.android.com/tools/testing/activity_testing.html

No puedo decir con 100% de certeza que haya un método de matar aquí exactamente igual que Android, pero es el comienzo. Puede simular muchas partes del ciclo de vida de la actividad aquí, por lo que debería ser capaz de simular la muerte de un proceso.

También aquí hay un tutorial: http://developer.android.com/tools/testing/activity_test.html#StateManagementTests

Espero que esto ayude. Aclamaciones


Parece que desea probar onSaveInstanceState y onRestoreInstanceState .

Prueba en dispositivo real: echa un vistazo a la aplicación SetAlwaysFinish .

Prueba en el emulador: checkout Destruye inmediatamente la opción de actividades en la aplicación Dev Tools en el emulador de Android.


Presione el botón Inicio y coloque la aplicación en primer plano. Luego detenga o mate el proceso desde DDMS o ADB.


Puede hacer los siguientes pasos para reproducir el comportamiento buscado:

  1. Abra su aplicación, vaya a la actividad principal
  2. Use el panel de notificaciones para navegar a cualquier otra aplicación de pantalla completa (por ejemplo, a la configuración del sistema, en la esquina superior derecha)
  3. Mate su proceso de solicitud
  4. Presione el botón Atrás

También puede conectarse a su dispositivo / emulador desde la terminal con adb shell , luego obtener el PID de su proceso con ps | grep <your_package_name ps | grep <your_package_name y ejecute kill -9 <pid> . A continuación, abra su aplicación minimizada del selector de aplicaciones recientes y se reiniciará la última actividad