Android: cancella lo stack posteriore


330

In Android ho alcune attività, diciamo A, B, C.

In A, utilizzo questo codice per aprire B:

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

In B, utilizzo questo codice per aprire C:

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

Quando l'utente tocca un pulsante in C, voglio tornare ad A e cancellare lo stack posteriore (chiudere sia B che C). Quindi, quando l'utente utilizza il pulsante Indietro B e C non viene visualizzato, ho provato quanto segue:

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

Ma B e C vengono ancora visualizzati se utilizzo il pulsante Indietro quando torno all'attività A. Come posso evitare questo?

Risposte:


438

Prova ad aggiungere FLAG_ACTIVITY_NEW_TASKcome descritto nei documenti per FLAG_ACTIVITY_CLEAR_TOP:

Questa modalità di avvio può anche essere utilizzata con buoni risultati in combinazione con FLAG_ACTIVITY_NEW_TASK: se utilizzata per avviare l'attività di root di un'attività, porta in primo piano qualsiasi istanza attualmente in esecuzione di quell'attività, quindi la cancella al suo stato principale. Ciò è particolarmente utile, ad esempio, quando si avvia un'attività dal gestore delle notifiche.

Quindi il tuo codice da lanciare Asarebbe:

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
Grazie ma ci ho provato. Ancora quando tocco il pulsante Indietro dopo che mostra di nuovo C. Cosa posso perdere?
Martin,

4
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
Dzeikei,

8
non funziona per me, tuttavia chiamare finish () sull'attività di origine fa quello che mi serviva per raggiungere
2cupsOfTech

10
Ho avuto lo stesso problema che non funzionava. Ciò che mi ha risolto è stato chiamare finish () dopo aver iniziato la nuova attività
Arno,

20
Ho anche aggiunto un altro intento intento = nuovo intento (SingUpActivity.this, LoginActivity.class); intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity (intento); finire();
Sam,

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

8
Con tutto il rispetto per la CLEAR_TOPbandiera - questa combinazione è l'UNICA che ha completamente cancellato l'intero stack e reso la nuova attività l'unica nella app. Grazie!
Aviel Gross

8
Qual è la differenza tra questa e la risposta accettata?
Yuri Heupa,

7
Grazie, la differenza con la risposta accettata è che con questa bandiera non abbiamo bisogno di chiamare activity.finish
Pablo Cegarra

1
FLAG_ACTIVITY_CLEAR_TASK ha funzionato perfettamente insieme a NEW_TASK
Shamsul Arefin Sajib

1
Questa dovrebbe essere la risposta accettata. Grazie mille.
MD Danish Ansari,

77

Che dire dell'aggiunta nel file manifest per l'attività correlata:

android:noHistory="true"

alla definizione di attività di B e C? Non verranno aggiunti allo zaino. Non sono sicuro che sia quello che vuoi.


3
Fai molta attenzione durante l'utilizzo di questo: se stai utilizzando il login con FB o qualsiasi tipo simile di funzionalità
Skynet

2
@Skynet Why? Quali sono i problemi associati a farlo?
Alfie Woodland,

8
Quando si passa il controllo a FB per l'accesso da una pagina con nessuna storia vera, l'app FB non riesce ora ad atterrare dopo aver effettuato l'accesso, nel mio caso stava tornando alla schermata principale del telefono e ho quasi perso il lavoro!
Skynet,

Questo non consente a un'attività aggiunta allo backstack .... questa non è la soluzione corretta.
Tarun,

Esattamente che sto cercando
Masum,

63

Questo mi dà fastidio per molto tempo. Finalmente l'ho risolto facendo questo:

Nel frammento, utilizzare:

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

In Attività, utilizzare (aggiungere un altro flag di intento Intent.FLAG_ACTIVITY_CLEAR_TASKrispetto al frammento):

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
Se stai utilizzando androidannotations, devi aggiungere: Intent.FLAG_ACTIVITY_CLEAR_TASK
yosafatade,

Il solutioin di attività ha funzionato bene per me. Anche se penso che con API 16 la soluzione di Daniel Schuler sia più semplice.
PhilippS,

Grazie yosafatade, era quello che mi mancava!
Marty Miller,

30
  1. Aggiungi android:launchMode="singleTop"all'elemento attività nel tuo manifest per l'attività A
  2. Quindi utilizzare intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) e intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)quando si avvia l'attività A

Ciò significa che quando viene avviata l'attività A, tutte le attività al di sopra di essa vengono cancellate in modo che A sia in cima. Viene creato un nuovo back stack con A alla radice e l'utilizzo singleTopti assicura di avviare sempre una volta (poiché A è ora in cima a causa di ..._CLEAR_TOP).


3
Sì. questo è quello che sto usando ora ma non lo fa. Ancora C compare quando premo il pulsante Indietro.
Martin,

Strano, l'ho usato in un progetto e funziona benissimo ... premendo indietro mi porta alla schermata principale. Forse c'è qualcos'altro che sta succedendo. Potresti pubblicare il tuo manifest?
Joseph Earl,

Ho riavviato l'emulatore e ora sembra funzionare proprio come hai detto. Grazie mille per il vostro aiuto!
Martin,

singleTop non dovrebbe avere nulla a che fare con la cancellazione dello stack.
stdout,

29

A partire da API 16 (Jelly Bean), puoi semplicemente chiamare finishAffinity().

Ora puoi anche chiamare ActivityCompat.finishAffinity(Activity activity)con la libreria di compatibilità.

Assicurati di impostare taskAffinity nel manifest su un nome pacchetto univoco per quel gruppo di attività.

Per ulteriori informazioni:
http://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#finishAffinity%28android.app.Activity%29


Soluzione davvero semplice e intuitiva se sei informato su API 16. Ha funzionato per me!
PhilippS,

3
promemoria: questo funzionerà solo per attività che condividono lo stesso compito Nome affinità
Ryan

questo funziona solo se hai una sola attività nella storia.
dal

17

Prova a usare

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

e non

intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

11

Se la tua applicazione ha una versione minima di sdk 16, puoi usarla finishAffinity ()

Termina questa attività e tutte le attività immediatamente sottostanti nell'attività corrente che hanno la stessa affinità.

Questo funziona per me Nella schermata Pagamento principale rimuovi tutte le attività di back-stack,

 @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

Per ricerche future, prova questo codice.

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

Queste bandiere finalmente hanno funzionato per me. Quello che ho fatto è stato iniziare la stessa attività in cui mi trovavo con queste bandiere e un EXIT booleano extra = true. In onCreate () ho controllato i parametri di avvio di EXIT e ho chiamato finish () se era impostato su true. È una seccatura solo per chiudere la tua app.
Janne Oksanen,

8

Usa finishAffinity (); nell'attività C all'avvio dell'attività A per cancellare le attività di backstack.


solo questa risposta funziona per me. Intent.FLAG_ACTIVITY_CLEAR_TOP e Intent.FLAG_ACTIVITY_NEW_TASK non sono richiesti
nuttynibbles

7

Utilizzare questo codice per iniziare una nuova attività e chiudere o distruggere tutti gli altri stack di attività o back stack.

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

Ho trovato una soluzione interessante che potrebbe aiutare. L'ho fatto nel mio onBackPressed()metodo.

finishAffinity();
finish();

FinishAffinityrimuove la connessione dell'attività esistente al suo stack. E poi finish ti aiuta a uscire da quell'attività. Che alla fine uscirà dall'applicazione.


4

Ho trovato le risposte qui un po 'fuorvianti perché il codice nella domanda originale sembra funzionare bene per me?

Poiché A è l'attività di root, avviandola da B o C solo con FLAG_ACTIVITY_CLEAR_TOP rimuove B e C dallo stack posteriore.


4

In kotlin è quasi uguale a java. Solo | il simbolo è sostituito da o testo. Quindi, è scritto come-

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

3

Ho provato tutte le soluzioni e nessuna ha funzionato individualmente per me. La mia soluzione è:

Dichiara Activity Acome SingleToputilizzando [android:launchMode="singleTop"]manifest di Android.

Ora aggiungi i seguenti flag durante il lancio Ada qualsiasi luogo. Cancella lo stack.

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_TOPnon funzionerà in questo caso. Si prega di utilizzare(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)

Per maggiori dettagli, consulta questa documentazione.


2

Sembra a me come è necessario iniziare Activity Cda Activity Btramite startActivityForResult(). Quando fai clic su un pulsante Activity C, chiama setResult(RESULT_OK)e finish()così Activity Cè finito. In Activity B, potresti avere la onActivityResult()risposta invocando anche finish()se stesso e verrai quindi riportato a Activity A.


7
Sì, ma se ci sono 42 attività tra A e C, questo sarà piuttosto noioso. La bandiera FLAG_ACTIVITY_CLEAR_TOP dovrebbe fare direttamente ciò che l'OP vuole.
Guillaume Brunerie,

Questo sarebbe un modo meno che ottimale per ottenere ciò che l'OP vuole e, come ha detto @Guillaume, richiederebbe il codice in tutte le attività tra il root e la parte superiore dello stack.
Jake Basile,

Debitamente annotato. Queste sono bandiere di cui ho bisogno di conoscere apparentemente.
Massimo

1

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


1

È possibile utilizzare questo esempio per chiamare il Activity AdaActivity C

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


1

per me l'aggiunta ha Intent.FLAG_ACTIVITY_CLEAR_TASKrisolto il 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 avanzato e riutilizzabile:

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

intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK

Se lo usi più di una volta, crea una funzione di estensione Intento

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

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

intent.clearStack()

Se è necessaria l'opzione per aggiungere ulteriori flag in altre situazioni, aggiungere 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
}

0

Inoltre FLAG_ACTIVITY_CLEAR_TOP, puoi provare ad aggiungere Intent.FLAG_ACTIVITY_SINGLE_TOPanche:

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


Ciò influenzerebbe solo l'attività nella parte superiore dello stack, non la radice di esso.
Jake Basile,

0

Il codice fornito funziona correttamente. Ho provato nell'esempio del ciclo di vita dell'applicazione.

Non ho B e C nello stack posteriore dopo aver avviato l'attività A con flag, FLAG_ACTIVITY_CLEAR_TOP


0

ho chiamato activity_name.this.finish()dopo aver iniziato un nuovo intento e ha funzionato per me.

I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"

Ma non funzionerà per me ... Non sto suggerendo questa soluzione per l'uso ma se l'impostazione del flag non funziona per te di quanto tu possa provare questo .. Ma comunque ti consiglio di non usarlo


0

Aggiungi NO Flag storico nell'intento.

Nell'attività B, avvia l'attività C come di seguito >>>>>>

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

0

In manifest

android:launchMode="singleTask"

e

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

0

O aggiungi questo al tuo Activity BeActivity C

android:noHistory="true"

o Override onBackPressedfunzione per evitare di premere indietro con a return.

@Override
public void onBackPressed() {
   return;
}

0

Utilizzare il metodo setFlags () per cancellare il retro aperto per aprire tutte le attività e avviare yourActvity

Intent intent = new Intent(getApplicationContext(), yourActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
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.