El uso de FLAG_ACTIVITY_REORDER_TO_FRONT para cambiar entre las actividades de la interfaz de usuario que se ejecutan de forma persistente provoca un error "sin foco de ventana"

Mi objetivo es mantener vivas dos actividades de interfaz de usuario y cambiar entre ellas a voluntad sin tener que matarlas o reiniciarlas. Pero hay un efecto secundario grave al usar FLAG_ACTIVITY_REORDER_TO_FRONT para hacer esto: una pérdida de foco de ventana cuando reanudo una actividad anterior (que se está ejecutando actualmente en segundo plano).

He demostrado este problema al pasar 5 minutos creando una aplicación sencilla con dos actividades "Hello World".

  1. La aplicación comienza con la actividad A, que simplemente muestra un botón (nada más) llamado "Lanzamiento B".
  2. Pulse este botón para ejecutar startActivity(FLAG_ACTIVITY_REORDER_TO_FRONT, ActivityB.class).
  3. Actividad B se activa, que muestra simplemente muestra un botón llamado "Lanzamiento A".
  4. Pulse este botón para ejecutar startActivity(FLAG_ACTIVITY_REORDER_TO_FRONT, ActivityA.class).
  5. onResume() Actividad A se llama como se espera y todo se ve bien (puedo ver el contenido de la Actividad A de nuevo).
  6. Presione la tecla Atrás del dispositivo y este conjunto de errores se producirá el 100% del tiempo:

E / ActivityManager (513): Razón: Se ha agotado el tiempo de espera de envío de la entrada (espera porque ninguna ventana tiene foco, pero hay una aplicación enfocada que eventualmente puede agregar una ventana cuando finalice la puesta en marcha).

I / WindowState (513): WIN DEATH: Ventana {5294687c u0 com.android.launcher / com.android.launcher2.Launcher}

W / ViewRootImpl (8066): Evento de eliminación debido a ningún foco de ventana : KeyEvent {action = ACTION_DOWN, keyCode = KEYCODE_BACK, scanCode = 0, metaState = 0, flags = 0xc8, repeatCount = 1, eventTime = 14965546, downTime = 14965045, deviceId = -1, source = 0x101}

(El resultado práctico de la ventana de muerte es esencialmente un "bloqueo" desde el punto de vista del usuario – Android lanza al usuario de la aplicación de nuevo a la pantalla de inicio, aunque técnicamente la aplicación sigue funcionando en segundo plano.

He depurado esto y encontré que la razón de la actividad A es visible, pero no tiene enfoque es porque la actividad A onWindowFocusChanged () no se llama como lo hace normalmente (aunque onResume () se llama). Esto tiene algo que ver con el hecho de que la Actividad B sigue activa en segundo plano (aunque claramente B ha perdido el foco – onWindowFocusChanged (false) fue llamado para B, así como onStop ()). Sé esto porque después del paso 4 anterior si llamo inmediatamente finish () en la Actividad B, la Actividad A de onWindowFocusChanged (true) SERÁ llamado y todo es normal. El hecho de que la Actividad B esté todavía activa pero no enfocada de alguna manera interfiere con la Actividad A recuperando el foco como debería. ¿Es este un error de Android o me estoy perdiendo algo?

Tenga en cuenta que si la Actividad A tenía varias vistas en ella y yo tocaba una de esas vistas después del paso 6 anterior, obtendría el mismo error "Caída del evento debido al error de no centrarse en la ventana", aunque no al 100% del tiempo por alguna razón .

La solución proporcionada en https://code.google.com/p/android/issues/detail?id=63570#c15 funcionó bastante bien para resolver el problema de Actividad que no obtuvo el foco de la ventana:

 protected void onNewIntent(Intent intent) { super.onNewIntent(intent); if ((intent.getFlags() | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) > 0) { if (android.os.Build.VERSION.SDK_INT >= 19 && !isTaskRoot()) { ActivityManager tasksManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); tasksManager.moveTaskToFront(getTaskId(), ActivityManager.MOVE_TASK_NO_USER_ACTION); } } } 

Esto también necesitará el permiso en AndroidManifest.xml

 <uses-permission android:name="android.permission.REORDER_TASKS" /> 

En realidad, me encuentro con este problema en la prueba de Espresso obtener este error:

java.lang.RuntimeException: Waited for the root of the view hierarchy to have window focus and not be requesting layout for over 10 seconds. If you specified a non default root matcher, it may be picking a root that never takes focus. Otherwise, something is seriously wrong.

  • Popup (usando PopupWindow o Dialog) llena el ancho de la pantalla sin razón aparente
  • Elemento de posición de Android en la pantalla
  • ¿Por qué no funciona la etiqueta de viewport en el Galaxy Nexus / Android 4?
  • Arquitectura de la GUI de Android - relación entre Superficie / vista / ventana / lienzo
  • TYPE_KEYGUARD mantiene el modo de pantalla completa después de realizar una llamada
  • Cómo escalar el video en un SurfaceView más grande que la ventana en Android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.