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?

Martín
fuente

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.
Jake Basile
fuente
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);
diesel
fuente
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.

Dominik Helleberg
fuente
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);
Geng Jiawen
fuente
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).

Joseph Earl
fuente
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

Daniel Schuler
fuente
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);
Muhammad Aamir Ali
fuente
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

Jaydeep purohit
fuente
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();
GeetT
fuente
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.

baswaraj
fuente
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);
Pankaj Talaviya
fuente
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.
Firzan Shaikh
fuente
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.

Sujith Royal
fuente
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.

ianjoyner
fuente
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)
Exigente05
fuente
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();
Tarun
fuente
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.

Ashish Saini
fuente
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.

Maximus
fuente
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);

Abhijeet
fuente
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);

Vipin Yadav
fuente
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();
Mohamed Mo'nes
fuente
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
}
Gibolt
fuente
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);

James
fuente
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

Sathesh
fuente
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

Swap-IOS-Android
fuente
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();
Arun Sharma
fuente
0

En manifiesto

android:launchMode="singleTask"

y

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
veintiuna
fuente
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;
}
Renjith JR
fuente
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);
Pankaj Talaviya
fuente