Android: elimine todas las actividades anteriores de la pila de actividades

119

Cuando hago clic en el botón Cerrar sesión en mi actividad de perfil, quiero llevar al usuario a la página de inicio de sesión , donde necesita usar nuevas credenciales.

Por lo tanto, usé este código:

Intent intent = new Intent(ProfileActivity.this,
        LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

en el onButtonClickbotón Cerrar sesión.

Pero el problema es que cuando hago clic en el botón Atrás del dispositivo en la Actividad de inicio de sesión, me lleva a la Actividad de perfil. Esperaba que la aplicación se cerrara cuando presione el botón de retroceso del dispositivo en LoginActivity.

¿Qué estoy haciendo mal?

También agregué android:launchMode="singleTop"en el manifiesto de mi LoginActivity

Gracias

Archie.bpgc
fuente
@GauravVashisth Estaba siguiendo esta solución stackoverflow.com/questions/5794506/…
Archie.bpgc
@ abbas.aniefa Esa solución es un poco complicada. ¿Es esa la única forma de borrar todo el backstack? Como tengo más de 30 actividades, debería escribir este código de transmisión para todas ellas
Archie.bpgc
intente esto entonces, stackoverflow.com/questions/10961481/… . El uso de Broadcast es una mejor solución.
abbas.aniefa
Otro enfoque que puede usar para cerrar la sesión, una vez que cierre la sesión, almacene una bandera en las preferencias compartidas y en cada método onRestart () de una actividad, puede verificar este valor de variable si está establecido en verdadero, puede finalizar la actividad actual. así que no importa cuántas actividades estén abiertas en segundo plano. esto terminaría toda tu actividad.
Hiren Dabhi
Su código original realmente funciona para el nivel de API 11 o superior con un ajuste. Solo necesita juntar las banderas en una sola llamada: intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);obtuve la respuesta de esta pregunta: stackoverflow.com/questions/3473168/…
jokeefe

Respuestas:

302

La solución propuesta aquí funcionó para mí:

Java

Intent i = new Intent(OldActivity.this, NewActivity.class);
// set the new task and clear flags
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);

Kotlin

val i = Intent(this, NewActivity::class.java)
// set the new task and clear flags
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(i)

Sin embargo, requiere un nivel de API> = 11.

kgiannakakis
fuente
Chicos, lean la documentación de FLAG_ACTIVITY_CLEAR_TASK.Esta es la forma oficial de obtener. No es necesario cambiar todas las actividades de la aplicación.
AlikElzin-kilaka
Esto no funciona para las notificaciones stackoverflow.com/questions/24873131/…
Sam
Tengo mi minAPI = 16, por lo que funciona perfectamente bien para mí. Sin embargo, noté que la ejecución de la vista es un poco lenta con API> 21 y fluida con API <21. ¿Alguien tiene el mismo problema?
Red M
1
Esto creará una nueva tarea para las actividades
Rohit
@kgiannakakis No hay duda de que la solución funciona si solo tenemos una tarea (pila de actividades), pero cuando tenemos varias tareas (pila de actividades) no funciona. por ejemplo, digamos que tengo cuatro actividades para mi aplicación A, B, C y D. Supongamos que tengo dos pilas de actividades A-> B-> C (fondo) & D-> A-> B (primer plano) y If I llamar a la actividad A de mi pila actual (D-> A-> B) con filtro de intención lo que sugirió qué sucederá, borre mi pila actual (D-> A-> B) y abra la actividad A y cuando presione hacia atrás cerrar aplicación, pero si presiono el botón de aplicación reciente, puedo ver dos pilas traseras de mi aplicación allí.
Rahul Pareta
31

Aquí hay una solución para borrar todas las actividades de su aplicación cuando usa el botón de cierre de sesión.

Cada vez que inicie una actividad, hágalo así:

Intent myIntent = new Intent(getBaseContext(), YourNewActivity.class);
startActivityForResult(myIntent, 0);

Cuando desee cerrar toda la aplicación, haga lo siguiente:

setResult(RESULT_CLOSE_ALL);
finish();

RESULT_CLOSE_ALL es una variable global final con un número entero único para indicar que desea cerrar todas las actividades.

Luego defina la onActivityResult(...)devolución de llamada de cada actividad para que cuando una actividad regrese con el valor RESULT_CLOSE_ALL, también llame a finish():

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch(resultCode)
    {
    case RESULT_CLOSE_ALL:
        setResult(RESULT_CLOSE_ALL);
        finish();
    }
    super.onActivityResult(requestCode, resultCode, data);
}

Esto provocará un efecto de cascada que cerrará todas tus actividades.

Sin embargo, este es un truco y se usa startActivityForResultde una manera que no fue diseñado para ser utilizado.

Quizás una mejor manera de hacer esto sería usar receptores de transmisión como se muestra aquí:

Al cerrar la sesión, borre la pila del historial de actividades, evitando que el botón "Atrás" abra las actividades que solo inician sesión

Consulte estos hilos para conocer otros métodos también:

Android: borrar la pila de tareas

Termina todas las actividades anteriores

Anup Cowkur
fuente
4
¿Es factible cuando tienes alrededor de 30 actividades en la historia?
Rakesh Gondaliya
4
debiera ser. Pero si tiene 30 actividades en la historia, es posible que desee considerar cambiar su diseño. 30 parece demasiado y Android podría acabar con ellos.
Anup Cowkur
1
Esta parece una mala forma de hacerlo. La pregunta de respuesta de @RakeshGondaliya parece legítima. 30 tal vez solo un número que representa un número "alto" de actividades. Esta respuesta se ve mejor: stackoverflow.com/a/3008684/243709
Aman Alam
Esta respuesta es genial. También puede utilizar la biblioteca EventBus para enviar eventos a sus actividades en backstack. github.com/greenrobot/EventBus
Stan
Es mejor usar la bandera simple 'Intent.FLAG_ACTIVITY_CLEAR_TOP' con intent
Naveen Rao
18

Para borrar la pila de actividades por completo, desea crear una nueva pila de tareas usando TaskStackBuilder, por ejemplo:

Intent loginIntent = LoginActivity.getIntent(context);
TaskStackBuilder.create(context).addNextIntentWithParentStack(loginIntent).startActivities();

Esto no solo creará una pila de tareas nueva y limpia, sino que también permitirá el funcionamiento adecuado del botón "arriba" si su LoginActivity tiene una actividad principal.

Matt Accola
fuente
1
Esta es la mejor manera de hacerlo.
Paul Burke
FLAG_ACTIVITY_NEW_TASKo finishAffinity()no funcionó para mí. Solo esta respuesta resolvió el propósito.
TM
Si salgo de la aplicación a través del botón Atrás y regreso a través del icono de la aplicación, se abre en la actividad que llamé a ese método. Así que no funciona para mí.
Tgo1014
17

finishAffinity()agregado en API 16. Uso ActivityCompat.finishAffinity()en versiones anteriores. Cuándo iniciará cualquier actividad con intent y finalizará la actividad actual. Ahora use ActivityCompat.finishAffinity()en su lugar finish(). terminará toda la actividad apilada debajo de la actividad actual. Funciona bien para mí.

Anurag Srivastava
fuente
3
En realidad esActivityCompat.finishAffinity()
The Berga
finishAffinity()también finaliza la actividad actual con todas las actividades presentes en la pila de actividades de la misma afinidad.
Neeraj Sewani
10

Que funciono para mi

Intent intent = new Intent(getApplicationContext(), HomeActivity.class);
ComponentName cn = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(cn);
startActivity(mainIntent);
Mongi Zaidi
fuente
5

Una posible solución que puedo sugerirle es que agregue android:launchMode="singleTop"en el manifiesto de mi ProfileActivity . y cuando se hace clic en cerrar sesión, puede cerrar la sesión comenzando de nuevo con LoginActivity. al cerrar la sesión, puede llamar a esto.

Intent in = new Intent(Profile.this,Login.class);
                in.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(in);
                finish();
Androide
fuente
Hice esto, lo que sucedió es: cuando hago clic en el botón Atrás, me lleva a Activty desde donde vine a
ProfileActivity
Esto puede suceder porque llegó a ProfileActivity llamando a un nuevo intent, no llamando a finish (); ¿Cómo está llegando a ProfileActivity desde otra actividad además de LoginActivty?
Android
Estoy cruzando la misma pregunta. Creo que no funcionaría cuando el sistema destruyera la intención de inicio de sesión, digamos debido a la falta de memoria.
user1914692
5

Para API 11+ puede usar Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASKasí:

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

Borrará totalmente todas las actividades anteriores y comenzará una nueva actividad.

madx
fuente
4

Puede intentarlo finishAffinity(), cierra todas las actividades actuales y funciona en Android 4.1 y versiones posteriores

Conejito
fuente
1
finishAffinity () agregado en API 16. Use ActivityCompat.finishAffinity () en la versión anterior. Funciona bien para mi.
Anurag Srivastava
2

También me enfrento al mismo problema.

en la actividad de inicio de sesión lo que hago es.

    Intent myIntent = new Intent(MainActivity.this, ActivityLoggedIn.class);
    finish();
    MainActivity.this.startActivity(myIntent);  

al cerrar la sesión

   Intent myIntent = new Intent(ActivityLoggedIn.this, MainActivity.class);
   finish();
   ActivityLoggedIn.this.startActivity(myIntent);

Esto funciona bien, pero cuando estoy en ActivityLoggedIn y minimizo la aplicación y hago clic en el icono del botón de inicio en el cajón de la aplicación, MainActivity comienza de nuevo: - / estoy usando la bandera

android:LaunchMode:singleTask 

para MainActivity.

Sujal Mandal
fuente
2

Utilice lo siguiente para activity

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

eliminar el indicador CLEAR_TASK para el uso de fragmentos.

Espero que esto pueda ser útil para algunas personas.

Aristo Michael
fuente
1

Solo mantén

Intent intent = new Intent(ProfileActivity.this,
    LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
startActivity(intent);
Gaurav Vashisth
fuente
4
No funciona. Todavía puedo ir a ProfileActivity usando el botón
Atrás
1

Ninguno de los indicadores de intención funcionó para mí, pero así es como lo arreglé:

Cuando un usuario se desconecta de una actividad, tenía que transmitir un mensaje de esa actividad, luego recibirlo en las actividades que quería cerrar, después de lo cual llamo a terminar (); y funciona bastante bien.

Ian Wambai
fuente
1

Prueba esto, funcionará:

Intent logout_intent = new Intent(DashboardActivity.this, LoginActivity.class);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(logout_intent);
finish();
Mohammad
fuente
1

En el nivel API 11 o superior, el uso FLAG_ACTIVITY_CLEAR_TASKy la FLAG_ACTIVITY_NEW_TASKbandera de Intención para borrar toda la pila de actividad.

Intent i = new Intent(OldActivity.this, NewActivity.class);
// set the new task and clear flags
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |  Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(i);
S.Sathya Priya
fuente
0

Utilizar este

Intent i1=new Intent(getApplicationContext(),StartUp_Page.class);
i1.setAction(Intent.ACTION_MAIN);
i1.addCategory(Intent.CATEGORY_HOME);
i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
i1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i1);
finish();
Prashant Kumar
fuente
¿Conocías setFlags y addFlags?
GvSharma
0

agregar al manifiesto para su actividad android:launchMode="singleTask"

Hally Trần
fuente
0

Kotlin avanzado y reutilizable:

Puede colocar la bandera directamente usando el método de establecimiento. En Kotlin ores el reemplazo de Java bitwise o |.

intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK

Si planea usar esto con regularidad, cree una función de extensión Intent

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 iniciar 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