Cómo detener y reiniciar una actividad en una prueba de instrumentación de Android?

Estoy tratando de escribir una prueba de instrumentación de actividad de Android que se detiene ( onPause() , luego onStop() ) y reinicia la actividad actual. Lo intenté

 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 vuelven a leer durante el método onStart() . Funciona cuando se hace manualmente, pero la prueba falla, de la cual extraigo la conclusión de que activity.finish() parece ser la forma incorrecta de detener y reiniciar una actividad.


Edit: 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 todos los manejadores de eventos terminaran. La línea siguiente detiene la ejecución de prueba hasta que la actividad está inactiva:

 getInstrumentation().waitForIdleSync() 

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

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

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

Causar la actividad pasa por el ciclo completo de recreación:

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

Lo que usted necesita es:

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

He expuesto la Instrumentation API recientemente y encontró un montón de actividad interesante ciclo de vida del método de disparo callActivityOnXXX (), la siguiente línea de código debe hacer lo complicado:

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

Diagrama del ciclo de vida de la actividad citando la guía oficial de dev: Introduzca aquí la descripción de la imagen

Intenté llamar a .finish (), setActivity (null), getActivity () y reinicia la actividad, pero para mí no estaba restaurando el estado. Intenté todas las otras respuestas en SO, y cada otro método para hacer esto podría encontrar en línea, y ninguno de ellos funcionó para mí. Después de mucha experimentación encontré los siguientes trabajos (nb: requiere API nivel 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 también se crea una nueva instancia del fragmento que había adjuntado a la actividad anteriormente en la prueba, y tanto la actividad como el fragmento restauran su estado de la manera esperada.

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

Edit: En una fecha posterior me di cuenta de cómo funciona esto. getActivity () funciona mediante el registro de ganchos que reciben nuevas Actividades que se están creando, que capturan la nueva Actividad creada por activity.recreate (). setActivity(null) era necesario para borrar el respaldo de caché interno getActivity, de lo contrario devolverá el antiguo 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 de las que se extiende.

Una buena manera de 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 manera conveniente de bombproof el patrón onPause / onStart.

Tal vez u podría tratar de guardar el nombre de su actividad, terminarlo … y utilizar la reflexión para obtener una nueva instancia de la .class para la nueva intención de crear …

Cambie su código de la siguiente manera:

 mActivity.finish(); setActivity(null); mActivity = this.getActivity(); 

Una explicación completa se puede encontrar en esta pregunta

  • ClassNotFoundException durante el instrumento de prueba de Android
  • Prueba de un servicio de accesibilidad de Android?
  • ¿Cómo probar una ListActivity burlándose de su contentProvider y así aislar la prueba de la base de datos?
  • ¿Cómo puedo ejecutar una sola prueba con gradle android
  • Destruye y reinicia la actividad con la biblioteca de soporte de pruebas
  • Optimizar el esfuerzo de prueba de Android
  • Cómo probar la aplicación empresarial android en varios dispositivos
  • ¿Pruebas beta de Google Play sin una aplicación publicada?
  • Android: ¿Cómo puedo guardar, borrar y restaurar SharedPreferences para la prueba de unidades?
  • Envío de mayúsculas a un TextEdit durante pruebas instrumentadas
  • ¿Cómo forzar un cambio de orientación en una prueba de instrumentación de Android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.