java - studio - ¿Cómo se usa Intent.FLAG_ACTIVITY_CLEAR_TOP para borrar la Pila de actividades?
navegar entre actividades android studio (10)
@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 volverá a crear en lugar de restablecerse en la parte superior.
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 pila es ... A, B, navegador, B
Espero que este código cambie la pila a ... A ... de modo que presionar una vez más lleve al usuario a la pantalla de inicio.
En cambio, parece cambiar la pila 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!
Agregar android: noHistory = "true" en el archivo de manifiesto.
<manifest >
<activity
android:name="UI"
android:noHistory="true"/>
</manifest>
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 intento que está comenzando aquí en su método onNewIntent (), o se terminará y se reiniciará con el nuevo intento.
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 intento, 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.
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
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 pila, 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);
}
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 / compilador. Pero desafortunadamente la actividad superviviente se reinicia, que no es lo que quiero. Parece que no hay una solución fácil.
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
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 lanzada.
Parece que funciona como necesito, la actividad no se reinicia y todas las demás actividades están cerradas.
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 intento 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 intento 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.
Uso tres banderas para resolver el problema:
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
Intent.FLAG_ACTIVITY_CLEAR_TASK |
Intent.FLAG_ACTIVITY_NEW_TASK);