2012-04-24 19 views
15

Estoy tratando de escribir una prueba de instrumentación de actividad de Android que se detiene (onPause(), luego onStop()) y reinicia la actividad actual. Intenté¿Cómo detener y reiniciar una actividad en una prueba de instrumentación de Android?

activity.finish(); 
activity = getActivity(); 

... pero eso no parece funcionar correctamente.

El objetivo de la prueba es afirmar que los datos del formulario se almacenan durante el método onPause() y volver a leerlos durante el método onStart(). Funciona al hacerlo manualmente, pero la prueba falla, de la que saco la conclusión de que activity.finish() parece ser la forma incorrecta de detener y reiniciar una actividad.


Editar: Mi problema principal parece haber sido un problema de sincronización. Después de reiniciar la actividad, el corredor de prueba no esperó a que finalizaran todos los manejadores de eventos. La siguiente línea se detiene la ejecución de la prueba hasta que la actividad está inactivo:

getInstrumentation().waitForIdleSync() 

Además de eso, echar un vistazo a la respuesta aceptada para obtener más información valiosa sobre el ciclo de vida.

+0

¿Qué parece exactamente que no funciona correctamente? – yorkw

+0

@yorkw He actualizado la pregunta, gracias por el comentario. –

+0

¿A qué te refieres cuando dices "hacerlo manualmente?" –

Respuesta

13

Al llamar (o desencadenar un cambio de orientación de la pantalla):

activity.finish(); // old activity instance is destroyed and shut down. 
activity = getActivity(); // new activity instance is launched and created. 

Causando la actividad pasan por el ciclo de vida completo de recreo:

onPause() -> onStop() -> onDestroy() -> onCreate() 

Lo que necesita es:

onPause() -> onStop() -> onRestart() 

expuse el Instrumentation API recientemente y encontré un montón de actividad interesante ciclo de vida Método E gatillo callActivityOnXXX(), la siguiente línea de código debe hacer el complicado:

MyActivity myActivity = getActivity(); 
// make activity falling into restart phase: 
getInstrumentation().callActivityOnRestart(myActivity); 

Actividad diagrama del ciclo de vida citando Guía oficial dev: enter image description here

+1

En realidad, ya probé la primera solución, y no pareció funcionar, como puede ver en mi pregunta. Pero tal vez tengas razón y el problema no esté relacionado ... Re tu segunda sugerencia, lo intentaré más adelante ... –

+0

@DaniloBargen, mira mi actualización. – yorkw

+0

que realmente lo hizo, ¡muchas gracias! :) ¿Te importaría poner esto en la parte superior de tu respuesta para que otros lo encuentren más fácilmente? –

0

Quizás u podría intentar salvar el nombre de su actividad, terminarlo ... y utilizar la reflexión para obtener una nueva instancia de la .class para el nuevo intento de crear ...

2

Una buena manera de para probar los eventos del ciclo de vida es a través de cambios en la orientación de la pantalla. En mi experiencia, es una forma conveniente de proteger contra explosiones el patrón onPause/onStart.

+0

Interesante idea. El problema con esto es que Android guarda los datos del formulario de forma predeterminada cuando cambia la orientación de la pantalla, por lo que realmente no cubre este caso de prueba ... –

+0

Un cambio en la orientación de la pantalla como resultado completo Ciclo de vida de la actividad: ... -> onPause () -> onStop() -> onDestroy() -> onCreate() -> onStart() -> ..., que tiene el mismo comportamiento de llamar a activity.finish(); actividad = getActivity(); – yorkw

+0

@DaniloBargen No creo que los datos del formulario se guarden por defecto cuando se destruye una actividad. –

10

intenté llamar .finish(), setActivity (nulo), getActivity() y reinicia la actividad, pero para mí no fue restaurar el estado. Probé todas las otras respuestas en SO, y cualquier otro método para hacer esto lo pude encontrar en línea, y ninguno de ellos funcionó para mí.Después de mucha experimentación he encontrado las siguientes obras (Nota: requiere el nivel API 11+):

getInstrumentation().runOnMainSync(new Runnable() { 
     @Override 
     public void run() { 
      activity.recreate(); 
     } 
    }); 
    setActivity(null); 
    activity = getActivity(); 

Cuando hago esto se crea una nueva instancia de actividad, y una nueva instancia del fragmento que se habían unido a la actividad anterior en la prueba también se crea, y tanto la actividad como el fragmento restauran su estado de la manera esperada.

No sé cómo funciona esto o por qué funciona, llegué a esta solución por prueba y error, y solo lo he probado en un Nexus 4 que ejecuta KitKat. No puedo garantizar que simule correctamente una actividad recreativa, pero funcionó para mis propósitos.

Editar: Más tarde descubrí cómo funciona esto. getActivity() funciona a través del registro de ganchos que reciben nuevas actividades que se crean, que capturan la nueva actividad creada por activity.recreate(). Se requirió setActivity(null) para borrar el respaldo de caché interno getActivity, de lo contrario devolverá el anterior y no buscará uno nuevo.

Puede ver cómo funciona esto al examinar el código fuente de las distintas clases de casos de prueba desde las que se extiende.

Cuestiones relacionadas