Android: rimuovi tutte le attività precedenti dallo stack precedente


119

Quando faccio clic sul pulsante Logout nella mia attività del profilo, desidero portare l'utente alla pagina di accesso , dove deve utilizzare le nuove credenziali.

Quindi ho usato questo codice:

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

nel onButtonClickpulsante Logout.

Ma il problema è che quando faccio clic sul pulsante Indietro del dispositivo sull'attività di accesso, mi porta a ProfileActivity. Mi aspettavo che l'applicazione si chiudesse quando premo il pulsante Indietro del dispositivo su LoginActivity.

Che cosa sto facendo di sbagliato?

Ho anche aggiunto android:launchMode="singleTop"nel manifest per la mia LoginActivity

Grazie


@GauravVashisth Stavo solo seguendo questa soluzione stackoverflow.com/questions/5794506/...
Archie.bpgc

@ abbas.aniefa Quella soluzione è un po 'complicata. È l'unico modo per cancellare tutto lo stack posteriore. Perché ho più di 30 attività, quindi dovrei scrivere questo codice di trasmissione per tutte
Archie.bpgc

prova questo quindi, stackoverflow.com/questions/10961481/… . L'uso di Broadcast è una soluzione migliore.
abbas.aniefa

un altro approccio che puoi usare per il logout, una volta che esegui il logout memorizza un flag in sharedpreferences e in ogni metodo onRestart () di un'attività puoi controllare questo valore della variabile se è impostato su true puoi terminare l'attività corrente. quindi non importa quante attività sono aperte in background. questo finirebbe tutta la tua attività.
Hiren Dabhi

Il tuo codice originale funziona effettivamente per il livello API 11 o superiore con una modifica. Hai solo bisogno di mettere le bandiere insieme in una singola chiamata: intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);ho avuto la risposta da questa domanda: stackoverflow.com/questions/3473168/...
jokeefe

Risposte:


304

La soluzione proposta qui ha funzionato per me:

Giava

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)

Tuttavia, richiede un livello API> = 11.


Ragazzi, leggete la documentazione di FLAG_ACTIVITY_CLEAR_TASK.Questo è il modo ufficiale per ottenere. Non è necessario modificare tutte le attività nell'app.
AlikElzin-kilaka

Questo non funziona per le notifiche stackoverflow.com/questions/24873131/…
Sam

Ho il mio minAPI = 16, quindi funziona perfettamente per me. Tuttavia, ho notato che l'esecuzione della vista è un po 'lenta con API> 21 e fluida con API <21. Qualcuno ha riscontrato lo stesso problema?
Red M

1
Questo creerà una nuova attività per le attività
Rohit

@kgiannakakis Senza dubbio la soluzione funziona se abbiamo una sola attività (stack di attività) ma quando abbiamo più attività (stack di attività) non funziona. ex- diciamo che ho quattro attività per la mia applicazione A, B, C e D. Supponiamo di avere due back stack di attività A-> B-> C (sfondo) e D-> A-> B (primo piano) e If I chiama l'attività A dal mio stack corrente (D-> A-> B) con il filtro intento ciò che hai suggerito cosa succederà cancella il mio stack corrente (D-> A-> B) e apri l'attività A e quando lo premo chiudi ma se premo il pulsante dell'app recente posso vedere due backstacks della mia app lì.
Rahul Pareta

31

Ecco una soluzione per cancellare tutte le attività dell'applicazione quando utilizzi il pulsante di disconnessione.

Ogni volta che avvii un'attività, avviala in questo modo:

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

Quando vuoi chiudere l'intera app, procedi come segue:

setResult(RESULT_CLOSE_ALL);
finish();

RESULT_CLOSE_ALL è una variabile globale finale con un numero intero univoco per segnalare che si desidera chiudere tutte le attività.

Quindi definisci la onActivityResult(...)richiamata di ogni attività in modo che quando un'attività ritorna con il valore RESULT_CLOSE_ALL, chiama anche 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);
}

Ciò causerà un effetto a cascata che chiude tutte le tue attività.

Questo è tuttavia un trucco e utilizza startActivityForResultin un modo che non è stato progettato per essere utilizzato.

Forse un modo migliore per farlo sarebbe usare i ricevitori di trasmissione come mostrato qui:

Alla disconnessione, cancella lo stack della cronologia delle attività, impedendo al pulsante "Indietro" di aprire le attività solo con accesso

Vedi questi thread anche per altri metodi:

Android: cancella lo stack posteriore

Termina tutte le attività precedenti


4
È fattibile quando hai circa 30 attività sulla storia?
Rakesh Gondaliya

4
dovrebbe essere. Ma se hai 30 attività nella storia, potresti prendere in considerazione la possibilità di cambiare il tuo design. 30 sembra un po 'troppo e Android potrebbe ucciderli da solo.
Anup Cowkur

1
Questo sembra un modo povero di farlo. La domanda di risposta di @RakeshGondaliya sembra legittima. 30 forse solo un numero che rappresenta un numero "elevato" di attività. Questa risposta sembra migliore: stackoverflow.com/a/3008684/243709
Aman Alam

Questa risposta è ottima. Puoi anche utilizzare la libreria EventBus per inviare eventi alle tue attività in backstack. github.com/greenrobot/EventBus
Stan

Meglio usare il semplice flag 'Intent.FLAG_ACTIVITY_CLEAR_TOP' con l'intento
Naveen Rao

18

Per cancellare completamente lo stack delle attività, si desidera creare un nuovo stack delle attività utilizzando TaskStackBuilder, ad esempio:

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

Questo non solo creerà un nuovo stack di attività pulito, ma consentirà anche il corretto funzionamento del pulsante "su" se la tua LoginActivity ha un'attività genitore.


1
Questo è il modo migliore per farlo.
Paul Burke

FLAG_ACTIVITY_NEW_TASKo finishAffinity()non ha funzionato per me. Solo questa risposta ha risolto lo scopo.
TM

Se lascio l'app tramite il pulsante Indietro e ritorno tramite l'icona dell'app, si apre nell'attività che ho chiamato quel metodo. Quindi non funziona per me.
Tgo1014

17

finishAffinity()aggiunto nell'API 16. Utilizzo ActivityCompat.finishAffinity()nelle versioni precedenti. Quando avvierai un'attività usando l'intento e finirai l'attività corrente. Ora usa ActivityCompat.finishAffinity()invece finish(). terminerà tutte le attività impilate sotto l'attività corrente. Funziona bene per me.


3
In realtà èActivityCompat.finishAffinity()
Il Berga

finishAffinity()termina anche l'attività corrente con tutte le attività presenti nel back stack della stessa affinità.
Neeraj Sewani

10

Cosa ha funzionato per me

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

5

Una possibile soluzione che posso suggerirti è aggiungere android:launchMode="singleTop"nel manifest per il mio ProfileActivity . e quando si fa clic sul logout è possibile disconnettersi ricominciando LoginActivity. al logout puoi chiamarlo.

Intent in = new Intent(Profile.this,Login.class);
                in.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(in);
                finish();

Ho fatto questo, quello che è successo è: quando faccio clic sul pulsante Indietro mi porta ad Activty da dove sono arrivato a ProfileActivity
Archie.bpgc

Questo può accadere perché sei arrivato a ProfileActivity chiamando un nuovo intento non chiamando finish (); Come vieni su ProfileActivity da altre attività oltre a LoginActivty?
Android

Sto attraversando la stessa domanda. Penso che non funzionerebbe quando l'intento di accesso è stato distrutto dal sistema, ad esempio a causa della mancanza di memoria.
user1914692

5

Per API 11+ puoi usare in Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASKquesto modo:

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

Cancellerà completamente tutte le attività precedenti e inizierà una nuova attività.


4

Puoi provare finishAffinity(), chiude tutte le attività correnti e funziona su Android 4.1 e versioni successive


1
finishAffinity () aggiunto nell'API 16. Utilizzare ActivityCompat.finishAffinity () nella versione precedente. Per me funziona bene.
Anurag Srivastava

2

Sto anche affrontando lo stesso problema ..

nell'attività di accesso quello che faccio è.

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

al logout

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

Funziona bene, ma quando sono in ActivityLoggedIn e riduco a icona l'app e faccio clic sull'icona del pulsante di avvio nel cassetto delle app, MainActivity ricomincia: - / Sto usando il flag

android:LaunchMode:singleTask 

per MainActivity.


2

Usa quanto segue per activity

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

rimuovere il flag CLEAR_TASK per l'utilizzo dei frammenti.

Spero che questo possa essere utile per alcune persone.


1

Mantieni e basta

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

4
La sua non funziona. Posso ancora andare su ProfileActivity usando il pulsante Indietro
Archie.bpgc

1

Nessuno dei flag di intenti ha funzionato per me, ma è così che l'ho risolto:

Quando un utente si disconnette da un'attività, ho dovuto trasmettere un messaggio da quell'attività, quindi riceverlo nelle attività che volevo chiudere dopo di che chiamo finish (); e funziona abbastanza bene.


1

Prova questo funzionerà:

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();

1

Nel livello API 11 o superiore, utilizza FLAG_ACTIVITY_CLEAR_TASKe FLAG_ACTIVITY_NEW_TASKcontrassegna su Intent per cancellare tutto lo stack di attività.

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

0

Usa questo

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();

sapevi setFlags e addFlags?
GvSharma

0

aggiungi a Manifest per la tua attività android:launchMode="singleTask"


0

Kotlin avanzato e riutilizzabile:

È possibile impostare il flag direttamente utilizzando il metodo setter. In Kotlin orè la sostituzione di Java bit per bit o |.

intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK

Se prevedi di usarlo regolarmente, crea una funzione di estensione Intent

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

È quindi possibile chiamare direttamente questa funzione prima di avviare l'intento

intent.clearStack()

Se hai bisogno dell'opzione per aggiungere ulteriori flag in altre situazioni, aggiungi un parametro opzionale alla funzione di estensione.

fun Intent.clearStack(additionalFlags: Int = 0) {
    flags = additionalFlags or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.