¿Cómo se usa Intent.FLAG_ACTIVITY_CLEAR_TOP para borrar la Pila de actividades?

He leído varias publicaciones sobre cómo usar esto, pero me falta algo, ya que no funciona para mí. Mi actividad A tiene launchmode = “singleTop” en el manifiesto. Inicia la actividad B, con launchmode = “singleInstance”. La actividad B abre un navegador y recibe e intenta regresar, razón por la cual es SingleInstance. Estoy tratando de anular el botón Atrás para que el usuario vuelva a la actividad A, y luego presione Atrás para salir de la actividad, en lugar de regresar a la actividad B nuevamente.

// activity B @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ECLAIR && keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) onBackPressed(); return super.onKeyDown(keyCode, event); } @Override public void onBackPressed() { startActivity(new Intent(this, UI.class) .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)); return; } 

Después de regresar del navegador, la stack es … A, B, navegador, B

Espero que este código cambie la stack a … A … de modo que presionar una vez más lleve al usuario a la pantalla de inicio.

En cambio, parece cambiar la stack a … A, B, Navegador, B, A … como si esas banderas no estuvieran allí.

Intenté llamar a finish () en la actividad B después de startActivity, pero luego el botón Atrás me lleva de vuelta al navegador.

¿Qué me estoy perdiendo? ¡Gracias!

@bitestar tiene la solución correcta, pero hay un paso más:

Estaba oculto en los documentos, sin embargo, debe cambiar el launchMode de la Activity a cualquier otra cosa que no sea standard . De lo contrario, se destruirá y se volverá a crear en lugar de restablecerse en la parte superior.

He comenzado la Actividad A-> B-> C-> D. Cuando se presiona el botón Atrás en la Actividad DI quiero ir a la Actividad A. Como A es mi punto de partida y por lo tanto ya está en la stack, todas las actividades en la parte superior de A se borran y no se puede volver a ninguna otra Actividad de A .

Esto realmente funciona en mi código:

 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { Intent a = new Intent(this,A.class); a.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(a); return true; } return super.onKeyDown(keyCode, event); } 

Para esto, uso el indicador FLAG_ACTIVITY_CLEAR_TOP para iniciar el Intent
(sin FLAG_ACTIVITY_NEW_TASK )

y launchMode = "singleTask" en manifiesto para la actividad iniciada.

Parece que funciona como necesito, la actividad no se reinicia y todas las demás actividades están cerradas.

Aunque esta pregunta ya tiene suficientes respuestas, pensé que alguien querría saber por qué esta bandera funciona de esta manera peculiar. Esto es lo que encontré en la documentación de Android.

La instancia actualmente en ejecución de la actividad B en el ejemplo anterior recibirá el nuevo bash que está comenzando aquí en su método onNewIntent (), o se terminará y se reiniciará con el nuevo bash.

Si ha declarado que su modo de lanzamiento es “múltiple” (el valor predeterminado) y no ha configurado FLAG_ACTIVITY_SINGLE_TOP en el mismo bash, entonces se terminará y se volverá a crear; para todos los demás modos de ejecución o si se establece FLAG_ACTIVITY_SINGLE_TOP, este Intent se entregará a la instancia actual onNewIntent ().

Entonces, O bien,
1 . Cambia el launchMode de launchMode de la Actividad A a algo más de lo estándar (es decir, singleTask o algo así). Entonces su bandera FLAG_ACTIVITY_CLEAR_TOP no reiniciará su Actividad A.

o,

2 . Use Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP como tu bandera. Entonces funcionará de la manera que desees.

Sé que ya hay una respuesta aceptada, pero no veo cómo funciona para el OP porque no creo que FLAG_ACTIVITY_CLEAR_TOP tenga sentido en su caso particular. Esa bandera es relevante solo con actividades en la misma tarea . Según su descripción, cada actividad está en su propia tarea : A, B y el navegador.

Algo que tal vez lo está echando es que A es singleTop, cuando debería ser singleTask. Si A es singleTop, y B inicia A, entonces se creará una nueva A porque A no está en la tarea de B. De la documentación para singleTop:

“Si ya existe una instancia de la actividad en la parte superior de la tarea actual , el sistema enruta el bash a esa instancia …”

Como B inicia A, la tarea actual es la tarea de B, que es para una sola instancia y, por lo tanto, no puede incluir A. Use singleTask para lograr el resultado deseado allí porque entonces el sistema encontrará la tarea que tiene A y traerá esa tarea al primer plano.

Por último, después de que B ha iniciado A, y el usuario presiona desde A, OP no quiere ver B ni el navegador. Para lograr esto, llamar a finish () en B es correcto; nuevamente, FLAG_ACTIVITY_CLEAR_TOP no eliminará las otras actividades en la tarea de A porque sus otras actividades están todas en tareas diferentes. Sin embargo, la pieza que le faltaba era que B también debería usar FLAG_ACTIVITY_NO_HISTORY cuando dispara el bash para el navegador. Nota: si el navegador ya se está ejecutando antes de siquiera iniciar la aplicación del OP, entonces, por supuesto, verá el navegador cuando presione desde A. Entonces, para realmente probar esto, asegúrese de abandonar el navegador antes de iniciar la aplicación.

FLAG_ACTIVITY_NEW_TASK es el problema aquí que inicia una nueva tarea. Solo quítalo y listo.

Bueno, te recomiendo que leas lo que hace cada Bandera antes de trabajar con ellos

Lea esto e indicadores de intención aquí

Inicialmente, también tuve problemas para hacer que FLAG_ACTIVITY_CLEAR_TOP funcionara. Finalmente lo conseguí para trabajar usando el valor de esto (0x04000000). Parece que hay un problema de Eclipse / comstackdor. Pero desafortunadamente la actividad superviviente se reinicia, que no es lo que quiero. Parece que no hay una solución fácil.

Agregar android: noHistory = “true” en el archivo de manifiesto.

    

Uso tres banderas para resolver el problema:

 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP| Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); 

Llamé a activity_name.this.finish() después de comenzar una nueva intención y funcionó para mí.

 I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK" 

Pero no funcionará para mí … No estoy sugiriendo esta solución para su uso, pero si configurar la bandera no funciona para usted, entonces puede intentar esto … Pero aún así lo recomiendo, no lo use