Android: borra la pila posterior


330

En Android tengo algunas actividades, digamos A, B, C.

En A, uso este código para abrir B:

Intent intent = new Intent(this, B.class);
startActivity(intent);

En B, uso este código para abrir C:

Intent intent = new Intent(this, C.class);
startActivity(intent);

Cuando el usuario toca un botón en C, quiero volver a A y borrar la pila de respaldo (cerrar B y C). Entonces, cuando el usuario usa el botón de retroceso B y C no aparecerá, he intentado lo siguiente:

Intent intent = new Intent(this, A.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
startActivity(intent);

Pero B y C siguen apareciendo si uso el botón Atrás cuando estoy de vuelta en la actividad A. ¿Cómo puedo evitar esto?

Respuestas:


438

Intente agregar FLAG_ACTIVITY_NEW_TASKcomo se describe en los documentos para FLAG_ACTIVITY_CLEAR_TOP:

Este modo de inicio también se puede usar con buenos resultados junto con FLAG_ACTIVITY_NEW_TASK: si se usa para iniciar la actividad raíz de una tarea, pondrá en primer plano cualquier instancia de esa tarea que se esté ejecutando actualmente y luego la borrará a su estado raíz. Esto es especialmente útil, por ejemplo, al iniciar una actividad desde el administrador de notificaciones.

Entonces su código para lanzar Asería:

Intent intent = new Intent(this, A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(intent);
CurrentActivity.this.finish(); // if the activity running has it's own context


// view.getContext().finish() for fragments etc.

28
Gracias pero he intentado esto. Todavía cuando toco el botón Atrás después de que muestra C nuevamente. ¿Qué me puedo perder?
Martin

44
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
dzeikei

8
no funciona para mí, sin embargo llamar acabado () en la actividad de la fuente hace lo que necesitaba para lograr
2cupsOfTech

10
Tuve el mismo problema que esto no estaba funcionando. Lo que me arregló fue llamar a terminar () después de comenzar la nueva actividad
Arno

20
También agregué una intención de intención clara más = nueva intención (SingUpActivity.this, LoginActivity.class); intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity (intento); terminar();
Sam

147
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

8
Con todo el respeto a la CLEAR_TOPbandera, esta combinación es la ÚNICA que borró por completo toda la pila e hizo que la nueva actividad sea la única en la aplicación. ¡Gracias!
Aviel Gross

8
¿Cuál es la diferencia entre esto y la respuesta aceptada?
Yuri Heupa

77
Gracias, la diferencia con la respuesta aceptada es que con esta bandera no necesitamos llamar a activity.finish
Pablo Cegarra

1
FLAG_ACTIVITY_CLEAR_TASK funcionó perfectamente junto con NEW_TASK
Shamsul Arefin Sajib

1
Esta debería ser la respuesta aceptada. Muchas gracias.
MD Danish Ansari

77

¿Qué pasa con la adición en el archivo de manifiestos para la actividad relacionada:

android:noHistory="true"

a la definición de actividad de B y C? No se agregarán al backstack. No estoy seguro si eso es lo que quieres.


3
Tenga mucho cuidado al usar esto: si está utilizando el inicio de sesión con FB o cualquier tipo de funcionalidad similar
Skynet

2
@Skynet ¿Por qué? ¿Cuáles son los problemas asociados con hacer esto?
Alfie Woodland

8
Cuando pasa el control a FB para iniciar sesión desde una página con nohistory como verdadero, la aplicación FB no sabe dónde aterrizar después de iniciar sesión en el usuario, en mi caso, estaba volviendo a la pantalla de inicio del teléfono y casi pierdo mi trabajo.
Skynet

Esto no permite que una actividad se agregue al backstack ... esta no es la solución correcta.
Tarun

Exactamente lo que estoy buscando
Masum

63

Esto me molesta por mucho tiempo. Finalmente lo resolví haciendo esto:

En fragmento, use:

Intent intent = new Intent(view.getContext(), A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(intent);

En Actividad, use (agregue un indicador de intención más en Intent.FLAG_ACTIVITY_CLEAR_TASKcomparación con el fragmento):

Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

1
Si está usando anotaciones androidan, debe agregar: Intent.FLAG_ACTIVITY_CLEAR_TASK
yosafatade

La solución de actividad funcionó bien para mí. Aunque creo que con API 16 la solución de Daniel Schuler es más fácil.
PhilippS

Gracias yosafatade, ¡eso era lo que me faltaba!
Marty Miller,

30
  1. Agregue android:launchMode="singleTop"al elemento de actividad en su manifiesto para la Actividad A
  2. Luego use intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) y intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)cuando comience la Actividad A

Esto significa que cuando se inicia la Actividad A, se borran todas las tareas que se encuentran encima para que A esté en la parte superior. Se crea una nueva pila posterior con A en la raíz, y el uso singleTopgarantiza que solo se inicie A una vez (ya que A ahora está en la parte superior debido a ..._CLEAR_TOP).


3
Si. Esto es lo que estoy usando ahora, pero eso no lo hace. Todavía C aparece cuando presiono el botón Atrás.
Martin

Extraño, lo usé en un proyecto y funciona bien ... presionar hacia atrás me lleva a la pantalla de inicio. Tal vez hay algo más pasando. ¿Podría publicar su manifiesto?
Joseph Earl

Reinicié el emulador y ahora parece estar funcionando tal como dijiste. ¡Muchas gracias por tu ayuda!
Martin

singleTop no debería tener nada que ver con limpiar la pila.
stdout

29

A partir de API 16 (Jelly Bean), solo puede llamar finishAffinity().

Ahora también puedes llamar ActivityCompat.finishAffinity(Activity activity)con la biblioteca de compatibilidad.

Asegúrese de establecer taskAffinity en el manifiesto en un nombre de paquete único para ese grupo de actividades.

Consulte para obtener más información:
http://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#finishAffinity%28android.app.Activity%29


Solución realmente fácil de usar si ya estás en API 16. ¡Trabajó para mí!
PhilippS

3
Recordatorio: esto solo funcionará para actividades que compartan la misma tarea Nombre de afinidad
Ryan

esto solo funciona si solo tiene una actividad en la historia.
enviado el

17

Intenta usar

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

y no

intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

11

Si su aplicación tiene un mínimo de SDK versión 16, entonces puede usar finishAffinity ()

Finalice esta actividad, así como todas las actividades inmediatamente debajo de ella en la tarea actual que tengan la misma afinidad.

Esto es trabajo para mí En la pantalla de Pago superior, elimine todas las actividades de acumulación,

 @Override
public void onBackPressed() {
         finishAffinity();
        startActivity(new Intent(PaymentDoneActivity.this,Home.class));
    } 

http://developer.android.com/reference/android/app/Activity.html#finishAffinity%28%29



8

Para futuras investigaciones, prueba este código.

Intent intent = new Intent(context, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();

Estas banderas finalmente funcionaron para mí. Lo que hice fue comenzar la misma actividad en la que estaba con estas banderas y un booleano extra EXIT = true. En onCreate (), verifiqué los parámetros de inicio de EXIT y llamé a finish () si estaba configurado como verdadero. Eso es una gran molestia solo para cerrar su propia aplicación.
Janne Oksanen

8

Use finishAffinity (); en la tarea C al iniciar la tarea A para borrar las actividades de backstack.


solo esta respuesta me funciona. Intent.FLAG_ACTIVITY_CLEAR_TOP y Intent.FLAG_ACTIVITY_NEW_TASK no son obligatorios
nuttynibbles

7

Use este código para comenzar una nueva Actividad y cierre o destruya todas las demás pilas de actividades o pilas traseras.

Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

5
Use finishAffinity() to clear all backstack with existing one.

Suppose, Activities A, B and C are in stack, and finishAffinity(); is called in Activity C, 

    - Activity B will be finished / removing from stack.
    - Activity A will be finished / removing from stack.
    - Activity C will finished / removing from stack.

5

Encontré una solución interesante que podría ayudar. Hice esto en mi onBackPressed()método.

finishAffinity();
finish();

FinishAffinityelimina la conexión de la actividad existente a su pila. Y luego terminar te ayuda a salir de esa actividad. Lo que eventualmente saldrá de la aplicación.


4

¿Encontré las respuestas aquí un poco engañosas porque el código en la pregunta original parece funcionar bien para mí?

Siendo A la actividad raíz, comenzar desde B o C solo con FLAG_ACTIVITY_CLEAR_TOP elimina B y C de la pila posterior.


4

En kotlin es casi lo mismo que java. Solo | el símbolo se reemplaza por o texto. Entonces, está escrito como ...

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)

3

Probé todas las soluciones y ninguna funcionó individualmente para mí. Mi solución es:

Declarar Activity Acomo SingleTopmediante el uso [android:launchMode="singleTop"]en manifiesto de Android.

Ahora agregue las siguientes banderas mientras se inicia Adesde cualquier lugar. Vaciará la pila.

Intent in = new Intent(mContext, A.class);
in.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK );
startActivity(in);
finish();

2

Intent.FLAG_ACTIVITY_CLEAR_TOPNo funcionará en este caso. Por favor use(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)

Para obtener más detalles, consulte esta documentación.


2

Me suena como que necesita para comenzar Activity Ca partir Activity Busando startActivityForResult(). Al hacer clic en un botón en Activity C, llamada setResult(RESULT_OK)y finish()así Activity Cse terminó. En Activity B, puede obtener la onActivityResult()respuesta también recurriendo finish()a sí mismo, y luego volverá a Activity A.


77
Sí, pero si hay 42 actividades entre A y C, esto será bastante tedioso. Se supone que la bandera FLAG_ACTIVITY_CLEAR_TOP debe hacer directamente lo que quiere el OP.
Guillaume Brunerie

Esta sería una forma menos que óptima de lograr lo que quiere el OP, y como dijo @Guillaume, requeriría código en todas las actividades entre la raíz y la parte superior de la pila.
Jake Basile

Debidamente anotado. Estas son banderas sobre las que necesito aprender aparentemente.
Maximus

1

logout.addFlags (Intent.FLAG_ACTIVITY_CLEAR_TASK); logout.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK);


1

Puede utilizar este ejemplo para llamar a su Activity AdeActivity C

Intent loout = new Intent(context, LoginActivity.class); loout.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); context.startActivity(loout);


1

para mí agregar Intent.FLAG_ACTIVITY_CLEAR_TASKsolucionó el problema

Intent i = new Intent(SettingsActivity.this, StartPage.class);
                i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP  | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(i);
finish();

1

Kotlin avanzado y reutilizable:

Puede establecer la bandera directamente utilizando el método setter. En Kotlin se orencuentra el reemplazo para Java o bit a bit |.

intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK

Si usa esto más de una vez, cree una función de extensión de intención

fun Intent.clearStack() {
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}

Luego puede llamar directamente a esta función antes de comenzar la intención

intent.clearStack()

Si necesita la opción de agregar indicadores adicionales en otras situaciones, agregue un parámetro opcional a la función de extensión.

fun Intent.clearStack(additionalFlags: Int = 0) {
    flags = additionalFlags or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}

0

Además FLAG_ACTIVITY_CLEAR_TOP, puede intentar agregar Intent.FLAG_ACTIVITY_SINGLE_TOPtambién:

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);


Eso solo afectaría la actividad en la parte superior de la pila, no la raíz de la misma.
Jake Basile

0

El código dado funciona correctamente. He intentado en la muestra del ciclo de vida de la aplicación.

No tengo B y C en la pila posterior después de comenzar la actividad A con bandera, FLAG_ACTIVITY_CLEAR_TOP


0

Llamé 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 la marca de configuración no funciona para usted, puede intentar esto ... Pero aún así, le recomiendo que no la use


0

Agregar NO bandera de historial en la intención.

En la actividad B, comience la actividad C como se muestra a continuación >>>>>>

Intent intent = new Intent(this, C.class);
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NO_HISTORY); 
startActivity(intent);
finish();

0

En manifiesto

android:launchMode="singleTask"

y

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

0

Agrega esto a tu Activity ByActivity C

android:noHistory="true"

o Override onBackPressedfunción para evitar presionar hacia atrás con a return.

@Override
public void onBackPressed() {
   return;
}

0

Use el método setFlags () para borrar la parte posterior abierta, cerrar todas las actividades e iniciar su actividad

Intent intent = new Intent(getApplicationContext(), yourActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.